WPS: Merged two cred_cb variables into the same one
[libeap.git] / src / wps / wps_enrollee.c
1 /*
2  * Wi-Fi Protected Setup - Enrollee
3  * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14
15 #include "includes.h"
16
17 #include "common.h"
18 #include "sha256.h"
19 #include "ieee802_11_defs.h"
20 #include "wps_i.h"
21 #include "wps_dev_attr.h"
22
23
24 static int wps_build_req_type(struct wpabuf *msg, enum wps_request_type type)
25 {
26         wpa_printf(MSG_DEBUG, "WPS:  * Request Type");
27         wpabuf_put_be16(msg, ATTR_REQUEST_TYPE);
28         wpabuf_put_be16(msg, 1);
29         wpabuf_put_u8(msg, type);
30         return 0;
31 }
32
33
34 static int wps_build_uuid_e(struct wpabuf *msg, const u8 *uuid)
35 {
36         wpa_printf(MSG_DEBUG, "WPS:  * UUID-E");
37         wpabuf_put_be16(msg, ATTR_UUID_E);
38         wpabuf_put_be16(msg, WPS_UUID_LEN);
39         wpabuf_put_data(msg, uuid, WPS_UUID_LEN);
40         return 0;
41 }
42
43
44 static int wps_build_mac_addr(struct wps_data *wps, struct wpabuf *msg)
45 {
46         wpa_printf(MSG_DEBUG, "WPS:  * MAC Address");
47         wpabuf_put_be16(msg, ATTR_MAC_ADDR);
48         wpabuf_put_be16(msg, ETH_ALEN);
49         wpabuf_put_data(msg, wps->mac_addr_e, ETH_ALEN);
50         return 0;
51 }
52
53
54 static int wps_build_config_methods(struct wpabuf *msg, u16 methods)
55 {
56         wpa_printf(MSG_DEBUG, "WPS:  * Config Methods");
57         wpabuf_put_be16(msg, ATTR_CONFIG_METHODS);
58         wpabuf_put_be16(msg, 2);
59         wpabuf_put_be16(msg, methods);
60         return 0;
61 }
62
63
64 static int wps_build_wps_state(struct wps_data *wps, struct wpabuf *msg)
65 {
66         wpa_printf(MSG_DEBUG, "WPS:  * Wi-Fi Protected Setup State");
67         wpabuf_put_be16(msg, ATTR_WPS_STATE);
68         wpabuf_put_be16(msg, 1);
69         wpabuf_put_u8(msg, WPS_STATE_CONFIGURED);
70         return 0;
71 }
72
73
74 static int wps_build_rf_bands(struct wps_data *wps, struct wpabuf *msg)
75 {
76         wpa_printf(MSG_DEBUG, "WPS:  * RF Bands");
77         wpabuf_put_be16(msg, ATTR_RF_BANDS);
78         wpabuf_put_be16(msg, 1);
79         wpabuf_put_u8(msg, WPS_RF_24GHZ | WPS_RF_50GHZ);
80         return 0;
81 }
82
83
84 static int wps_build_dev_password_id(struct wpabuf *msg, u16 id)
85 {
86         wpa_printf(MSG_DEBUG, "WPS:  * Device Password ID");
87         wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
88         wpabuf_put_be16(msg, 2);
89         wpabuf_put_be16(msg, id);
90         return 0;
91 }
92
93
94 static int wps_build_config_error(struct wps_data *wps, struct wpabuf *msg)
95 {
96         u16 err = WPS_CFG_NO_ERROR;
97         wpabuf_put_be16(msg, ATTR_CONFIG_ERROR);
98         wpabuf_put_be16(msg, 2);
99         if (wps && wps->authenticator && wps->wps->ap_setup_locked)
100                 err = WPS_CFG_SETUP_LOCKED;
101         wpa_printf(MSG_DEBUG, "WPS:  * Configuration Error (%d)", err);
102         wpabuf_put_be16(msg, err);
103         return 0;
104 }
105
106
107 static int wps_build_e_hash(struct wps_data *wps, struct wpabuf *msg)
108 {
109         u8 *hash;
110         const u8 *addr[4];
111         size_t len[4];
112
113         if (os_get_random(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0)
114                 return -1;
115         wpa_hexdump(MSG_DEBUG, "WPS: E-S1", wps->snonce, WPS_SECRET_NONCE_LEN);
116         wpa_hexdump(MSG_DEBUG, "WPS: E-S2",
117                     wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN);
118
119         if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) {
120                 wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for "
121                            "E-Hash derivation");
122                 return -1;
123         }
124
125         wpa_printf(MSG_DEBUG, "WPS:  * E-Hash1");
126         wpabuf_put_be16(msg, ATTR_E_HASH1);
127         wpabuf_put_be16(msg, SHA256_MAC_LEN);
128         hash = wpabuf_put(msg, SHA256_MAC_LEN);
129         /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
130         addr[0] = wps->snonce;
131         len[0] = WPS_SECRET_NONCE_LEN;
132         addr[1] = wps->psk1;
133         len[1] = WPS_PSK_LEN;
134         addr[2] = wpabuf_head(wps->dh_pubkey_e);
135         len[2] = wpabuf_len(wps->dh_pubkey_e);
136         addr[3] = wpabuf_head(wps->dh_pubkey_r);
137         len[3] = wpabuf_len(wps->dh_pubkey_r);
138         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
139         wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", hash, SHA256_MAC_LEN);
140
141         wpa_printf(MSG_DEBUG, "WPS:  * E-Hash2");
142         wpabuf_put_be16(msg, ATTR_E_HASH2);
143         wpabuf_put_be16(msg, SHA256_MAC_LEN);
144         hash = wpabuf_put(msg, SHA256_MAC_LEN);
145         /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
146         addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;
147         addr[1] = wps->psk2;
148         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
149         wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", hash, SHA256_MAC_LEN);
150
151         return 0;
152 }
153
154
155 static int wps_build_e_snonce1(struct wps_data *wps, struct wpabuf *msg)
156 {
157         wpa_printf(MSG_DEBUG, "WPS:  * E-SNonce1");
158         wpabuf_put_be16(msg, ATTR_E_SNONCE1);
159         wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
160         wpabuf_put_data(msg, wps->snonce, WPS_SECRET_NONCE_LEN);
161         return 0;
162 }
163
164
165 static int wps_build_e_snonce2(struct wps_data *wps, struct wpabuf *msg)
166 {
167         wpa_printf(MSG_DEBUG, "WPS:  * E-SNonce2");
168         wpabuf_put_be16(msg, ATTR_E_SNONCE2);
169         wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
170         wpabuf_put_data(msg, wps->snonce + WPS_SECRET_NONCE_LEN,
171                         WPS_SECRET_NONCE_LEN);
172         return 0;
173 }
174
175
176 static struct wpabuf * wps_build_m1(struct wps_data *wps)
177 {
178         struct wpabuf *msg;
179         u16 methods;
180
181         if (os_get_random(wps->nonce_e, WPS_NONCE_LEN) < 0)
182                 return NULL;
183         wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce",
184                     wps->nonce_e, WPS_NONCE_LEN);
185
186         wpa_printf(MSG_DEBUG, "WPS: Building Message M1");
187         msg = wpabuf_alloc(1000);
188         if (msg == NULL)
189                 return NULL;
190
191         methods = WPS_CONFIG_LABEL | WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD;
192         if (wps->pbc)
193                 methods |= WPS_CONFIG_PUSHBUTTON;
194
195         if (wps_build_version(msg) ||
196             wps_build_msg_type(msg, WPS_M1) ||
197             wps_build_uuid_e(msg, wps->uuid_e) ||
198             wps_build_mac_addr(wps, msg) ||
199             wps_build_enrollee_nonce(wps, msg) ||
200             wps_build_public_key(wps, msg) ||
201             wps_build_auth_type_flags(wps, msg) ||
202             wps_build_encr_type_flags(wps, msg) ||
203             wps_build_conn_type_flags(wps, msg) ||
204             wps_build_config_methods(msg, methods) ||
205             wps_build_wps_state(wps, msg) ||
206             wps_build_device_attrs(&wps->wps->dev, msg) ||
207             wps_build_rf_bands(wps, msg) ||
208             wps_build_assoc_state(wps, msg) ||
209             wps_build_dev_password_id(msg, wps->dev_pw_id) ||
210             wps_build_config_error(wps, msg) ||
211             wps_build_os_version(&wps->wps->dev, msg)) {
212                 wpabuf_free(msg);
213                 return NULL;
214         }
215
216         wps->state = RECV_M2;
217         return msg;
218 }
219
220
221 static struct wpabuf * wps_build_m3(struct wps_data *wps)
222 {
223         struct wpabuf *msg;
224
225         wpa_printf(MSG_DEBUG, "WPS: Building Message M3");
226
227         if (wps->dev_password == NULL) {
228                 wpa_printf(MSG_DEBUG, "WPS: No Device Password available");
229                 return NULL;
230         }
231         wps_derive_psk(wps, wps->dev_password, wps->dev_password_len);
232
233         msg = wpabuf_alloc(1000);
234         if (msg == NULL)
235                 return NULL;
236
237         if (wps_build_version(msg) ||
238             wps_build_msg_type(msg, WPS_M3) ||
239             wps_build_registrar_nonce(wps, msg) ||
240             wps_build_e_hash(wps, msg) ||
241             wps_build_authenticator(wps, msg)) {
242                 wpabuf_free(msg);
243                 return NULL;
244         }
245
246         wps->state = RECV_M4;
247         return msg;
248 }
249
250
251 static struct wpabuf * wps_build_m5(struct wps_data *wps)
252 {
253         struct wpabuf *msg, *plain;
254
255         wpa_printf(MSG_DEBUG, "WPS: Building Message M5");
256
257         plain = wpabuf_alloc(200);
258         if (plain == NULL)
259                 return NULL;
260
261         msg = wpabuf_alloc(1000);
262         if (msg == NULL) {
263                 wpabuf_free(plain);
264                 return NULL;
265         }
266
267         if (wps_build_version(msg) ||
268             wps_build_msg_type(msg, WPS_M5) ||
269             wps_build_registrar_nonce(wps, msg) ||
270             wps_build_e_snonce1(wps, plain) ||
271             wps_build_key_wrap_auth(wps, plain) ||
272             wps_build_encr_settings(wps, msg, plain) ||
273             wps_build_authenticator(wps, msg)) {
274                 wpabuf_free(plain);
275                 wpabuf_free(msg);
276                 return NULL;
277         }
278         wpabuf_free(plain);
279
280         wps->state = RECV_M6;
281         return msg;
282 }
283
284
285 static int wps_build_cred_ssid(struct wps_data *wps, struct wpabuf *msg)
286 {
287         wpa_printf(MSG_DEBUG, "WPS:  * SSID");
288         wpabuf_put_be16(msg, ATTR_SSID);
289         wpabuf_put_be16(msg, wps->wps->ssid_len);
290         wpabuf_put_data(msg, wps->wps->ssid, wps->wps->ssid_len);
291         return 0;
292 }
293
294
295 static int wps_build_cred_auth_type(struct wps_data *wps, struct wpabuf *msg)
296 {
297         wpa_printf(MSG_DEBUG, "WPS:  * Authentication Type");
298         wpabuf_put_be16(msg, ATTR_AUTH_TYPE);
299         wpabuf_put_be16(msg, 2);
300         wpabuf_put_be16(msg, wps->wps->auth_types);
301         return 0;
302 }
303
304
305 static int wps_build_cred_encr_type(struct wps_data *wps, struct wpabuf *msg)
306 {
307         wpa_printf(MSG_DEBUG, "WPS:  * Encryption Type");
308         wpabuf_put_be16(msg, ATTR_ENCR_TYPE);
309         wpabuf_put_be16(msg, 2);
310         wpabuf_put_be16(msg, wps->wps->encr_types);
311         return 0;
312 }
313
314
315 static int wps_build_cred_network_key(struct wps_data *wps, struct wpabuf *msg)
316 {
317         wpa_printf(MSG_DEBUG, "WPS:  * Network Key");
318         wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
319         wpabuf_put_be16(msg, wps->wps->network_key_len);
320         wpabuf_put_data(msg, wps->wps->network_key, wps->wps->network_key_len);
321         return 0;
322 }
323
324
325 static int wps_build_cred_mac_addr(struct wps_data *wps, struct wpabuf *msg)
326 {
327         wpa_printf(MSG_DEBUG, "WPS:  * MAC Address (AP BSSID)");
328         wpabuf_put_be16(msg, ATTR_MAC_ADDR);
329         wpabuf_put_be16(msg, ETH_ALEN);
330         wpabuf_put_data(msg, wps->wps->dev.mac_addr, ETH_ALEN);
331         return 0;
332 }
333
334
335 static struct wpabuf * wps_build_m7(struct wps_data *wps)
336 {
337         struct wpabuf *msg, *plain;
338
339         wpa_printf(MSG_DEBUG, "WPS: Building Message M7");
340
341         plain = wpabuf_alloc(500);
342         if (plain == NULL)
343                 return NULL;
344
345         msg = wpabuf_alloc(1000);
346         if (msg == NULL) {
347                 wpabuf_free(plain);
348                 return NULL;
349         }
350
351         if (wps_build_version(msg) ||
352             wps_build_msg_type(msg, WPS_M7) ||
353             wps_build_registrar_nonce(wps, msg) ||
354             wps_build_e_snonce2(wps, plain) ||
355             (wps->authenticator &&
356              (wps_build_cred_ssid(wps, plain) ||
357               wps_build_cred_mac_addr(wps, plain) ||
358               wps_build_cred_auth_type(wps, plain) ||
359               wps_build_cred_encr_type(wps, plain) ||
360               wps_build_cred_network_key(wps, plain))) ||
361             wps_build_key_wrap_auth(wps, plain) ||
362             wps_build_encr_settings(wps, msg, plain) ||
363             wps_build_authenticator(wps, msg)) {
364                 wpabuf_free(plain);
365                 wpabuf_free(msg);
366                 return NULL;
367         }
368         wpabuf_free(plain);
369
370         wps->state = RECV_M8;
371         return msg;
372 }
373
374
375 static struct wpabuf * wps_build_wsc_done(struct wps_data *wps)
376 {
377         struct wpabuf *msg;
378
379         wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_Done");
380
381         msg = wpabuf_alloc(1000);
382         if (msg == NULL)
383                 return NULL;
384
385         if (wps_build_version(msg) ||
386             wps_build_msg_type(msg, WPS_WSC_DONE) ||
387             wps_build_enrollee_nonce(wps, msg) ||
388             wps_build_registrar_nonce(wps, msg)) {
389                 wpabuf_free(msg);
390                 return NULL;
391         }
392
393         wps->state = wps->authenticator ? RECV_ACK : WPS_FINISHED;
394         return msg;
395 }
396
397
398 static struct wpabuf * wps_build_wsc_ack(struct wps_data *wps)
399 {
400         struct wpabuf *msg;
401
402         wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_ACK");
403
404         msg = wpabuf_alloc(1000);
405         if (msg == NULL)
406                 return NULL;
407
408         if (wps_build_version(msg) ||
409             wps_build_msg_type(msg, WPS_WSC_ACK) ||
410             wps_build_enrollee_nonce(wps, msg) ||
411             wps_build_registrar_nonce(wps, msg)) {
412                 wpabuf_free(msg);
413                 return NULL;
414         }
415
416         return msg;
417 }
418
419
420 static struct wpabuf * wps_build_wsc_nack(struct wps_data *wps)
421 {
422         struct wpabuf *msg;
423
424         wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_NACK");
425
426         msg = wpabuf_alloc(1000);
427         if (msg == NULL)
428                 return NULL;
429
430         if (wps_build_version(msg) ||
431             wps_build_msg_type(msg, WPS_WSC_NACK) ||
432             wps_build_enrollee_nonce(wps, msg) ||
433             wps_build_registrar_nonce(wps, msg) ||
434             wps_build_config_error(wps, msg)) {
435                 wpabuf_free(msg);
436                 return NULL;
437         }
438
439         return msg;
440 }
441
442
443 struct wpabuf * wps_enrollee_get_msg(struct wps_data *wps, u8 *op_code)
444 {
445         struct wpabuf *msg;
446
447         switch (wps->state) {
448         case SEND_M1:
449                 msg = wps_build_m1(wps);
450                 *op_code = WSC_MSG;
451                 break;
452         case SEND_M3:
453                 msg = wps_build_m3(wps);
454                 *op_code = WSC_MSG;
455                 break;
456         case SEND_M5:
457                 msg = wps_build_m5(wps);
458                 *op_code = WSC_MSG;
459                 break;
460         case SEND_M7:
461                 msg = wps_build_m7(wps);
462                 *op_code = WSC_MSG;
463                 break;
464         case RECEIVED_M2D:
465                 msg = wps_build_wsc_ack(wps);
466                 *op_code = WSC_ACK;
467                 if (msg) {
468                         /* Another M2/M2D may be received */
469                         wps->state = RECV_M2;
470                 }
471                 break;
472         case SEND_WSC_NACK:
473                 msg = wps_build_wsc_nack(wps);
474                 *op_code = WSC_NACK;
475                 break;
476         case WPS_MSG_DONE:
477                 msg = wps_build_wsc_done(wps);
478                 *op_code = WSC_Done;
479                 break;
480         default:
481                 wpa_printf(MSG_DEBUG, "WPS: Unsupported state %d for building "
482                            "a message", wps->state);
483                 msg = NULL;
484                 break;
485         }
486
487         if (*op_code == WSC_MSG && msg) {
488                 /* Save a copy of the last message for Authenticator derivation
489                  */
490                 wpabuf_free(wps->last_msg);
491                 wps->last_msg = wpabuf_dup(msg);
492         }
493
494         return msg;
495 }
496
497
498 static int wps_process_registrar_nonce(struct wps_data *wps, const u8 *r_nonce)
499 {
500         if (r_nonce == NULL) {
501                 wpa_printf(MSG_DEBUG, "WPS: No Registrar Nonce received");
502                 return -1;
503         }
504
505         os_memcpy(wps->nonce_r, r_nonce, WPS_NONCE_LEN);
506         wpa_hexdump(MSG_DEBUG, "WPS: Registrar Nonce",
507                     wps->nonce_r, WPS_NONCE_LEN);
508
509         return 0;
510 }
511
512
513 static int wps_process_enrollee_nonce(struct wps_data *wps, const u8 *e_nonce)
514 {
515         if (e_nonce == NULL) {
516                 wpa_printf(MSG_DEBUG, "WPS: No Enrollee Nonce received");
517                 return -1;
518         }
519
520         if (os_memcmp(wps->nonce_e, e_nonce, WPS_NONCE_LEN) != 0) {
521                 wpa_printf(MSG_DEBUG, "WPS: Invalid Enrollee Nonce received");
522                 return -1;
523         }
524
525         return 0;
526 }
527
528
529 static int wps_process_uuid_r(struct wps_data *wps, const u8 *uuid_r)
530 {
531         if (uuid_r == NULL) {
532                 wpa_printf(MSG_DEBUG, "WPS: No UUID-R received");
533                 return -1;
534         }
535
536         os_memcpy(wps->uuid_r, uuid_r, WPS_UUID_LEN);
537         wpa_hexdump(MSG_DEBUG, "WPS: UUID-R", wps->uuid_r, WPS_UUID_LEN);
538
539         return 0;
540 }
541
542
543 static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,
544                               size_t pk_len)
545 {
546         if (pk == NULL || pk_len == 0) {
547                 wpa_printf(MSG_DEBUG, "WPS: No Public Key received");
548                 return -1;
549         }
550
551         wpabuf_free(wps->dh_pubkey_r);
552         wps->dh_pubkey_r = wpabuf_alloc_copy(pk, pk_len);
553         if (wps->dh_pubkey_r == NULL)
554                 return -1;
555
556         return wps_derive_keys(wps);
557 }
558
559
560 static int wps_process_r_hash1(struct wps_data *wps, const u8 *r_hash1)
561 {
562         if (r_hash1 == NULL) {
563                 wpa_printf(MSG_DEBUG, "WPS: No R-Hash1 received");
564                 return -1;
565         }
566
567         os_memcpy(wps->peer_hash1, r_hash1, WPS_HASH_LEN);
568         wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", wps->peer_hash1, WPS_HASH_LEN);
569
570         return 0;
571 }
572
573
574 static int wps_process_r_hash2(struct wps_data *wps, const u8 *r_hash2)
575 {
576         if (r_hash2 == NULL) {
577                 wpa_printf(MSG_DEBUG, "WPS: No R-Hash2 received");
578                 return -1;
579         }
580
581         os_memcpy(wps->peer_hash2, r_hash2, WPS_HASH_LEN);
582         wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", wps->peer_hash2, WPS_HASH_LEN);
583
584         return 0;
585 }
586
587
588 static int wps_process_r_snonce1(struct wps_data *wps, const u8 *r_snonce1)
589 {
590         u8 hash[SHA256_MAC_LEN];
591         const u8 *addr[4];
592         size_t len[4];
593
594         if (r_snonce1 == NULL) {
595                 wpa_printf(MSG_DEBUG, "WPS: No R-SNonce1 received");
596                 return -1;
597         }
598
599         wpa_hexdump_key(MSG_DEBUG, "WPS: R-SNonce1", r_snonce1,
600                         WPS_SECRET_NONCE_LEN);
601
602         /* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */
603         addr[0] = r_snonce1;
604         len[0] = WPS_SECRET_NONCE_LEN;
605         addr[1] = wps->psk1;
606         len[1] = WPS_PSK_LEN;
607         addr[2] = wpabuf_head(wps->dh_pubkey_e);
608         len[2] = wpabuf_len(wps->dh_pubkey_e);
609         addr[3] = wpabuf_head(wps->dh_pubkey_r);
610         len[3] = wpabuf_len(wps->dh_pubkey_r);
611         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
612
613         if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
614                 wpa_printf(MSG_DEBUG, "WPS: R-Hash1 derived from R-S1 does "
615                            "not match with the pre-committed value");
616                 return -1;
617         }
618
619         wpa_printf(MSG_DEBUG, "WPS: Registrar proved knowledge of the first "
620                    "half of the device password");
621
622         return 0;
623 }
624
625
626 static int wps_process_r_snonce2(struct wps_data *wps, const u8 *r_snonce2)
627 {
628         u8 hash[SHA256_MAC_LEN];
629         const u8 *addr[4];
630         size_t len[4];
631
632         if (r_snonce2 == NULL) {
633                 wpa_printf(MSG_DEBUG, "WPS: No R-SNonce2 received");
634                 return -1;
635         }
636
637         wpa_hexdump_key(MSG_DEBUG, "WPS: R-SNonce2", r_snonce2,
638                         WPS_SECRET_NONCE_LEN);
639
640         /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
641         addr[0] = r_snonce2;
642         len[0] = WPS_SECRET_NONCE_LEN;
643         addr[1] = wps->psk2;
644         len[1] = WPS_PSK_LEN;
645         addr[2] = wpabuf_head(wps->dh_pubkey_e);
646         len[2] = wpabuf_len(wps->dh_pubkey_e);
647         addr[3] = wpabuf_head(wps->dh_pubkey_r);
648         len[3] = wpabuf_len(wps->dh_pubkey_r);
649         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
650
651         if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
652                 wpa_printf(MSG_DEBUG, "WPS: R-Hash2 derived from R-S2 does "
653                            "not match with the pre-committed value");
654                 return -1;
655         }
656
657         wpa_printf(MSG_DEBUG, "WPS: Registrar proved knowledge of the second "
658                    "half of the device password");
659
660         return 0;
661 }
662
663
664 static int wps_process_cred_e(struct wps_data *wps, const u8 *cred,
665                               size_t cred_len)
666 {
667         struct wps_parse_attr attr;
668         struct wpabuf msg;
669
670         wpa_printf(MSG_DEBUG, "WPS: Received Credential");
671         os_memset(&wps->cred, 0, sizeof(wps->cred));
672         wpabuf_set(&msg, cred, cred_len);
673         if (wps_parse_msg(&msg, &attr) < 0 ||
674             wps_process_cred(&attr, &wps->cred))
675                 return -1;
676
677         if (wps->wps->cred_cb)
678                 wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred);
679
680         return 0;
681 }
682
683
684 static int wps_process_creds(struct wps_data *wps, const u8 *cred[],
685                              size_t cred_len[], size_t num_cred)
686 {
687         size_t i;
688
689         if (wps->authenticator)
690                 return 0;
691
692         if (num_cred == 0) {
693                 wpa_printf(MSG_DEBUG, "WPS: No Credential attributes "
694                            "received");
695                 return -1;
696         }
697
698         for (i = 0; i < num_cred; i++) {
699                 if (wps_process_cred_e(wps, cred[i], cred_len[i]))
700                         return -1;
701         }
702
703         return 0;
704 }
705
706
707 static int wps_process_ap_settings_e(struct wps_data *wps,
708                                      struct wps_parse_attr *attr)
709 {
710         struct wps_credential cred;
711
712         if (!wps->authenticator)
713                 return 0;
714
715         if (wps_process_ap_settings(attr, &cred) < 0)
716                 return -1;
717
718         wpa_printf(MSG_INFO, "WPS: Received new AP configuration from "
719                    "Registrar");
720
721         if (wps->wps->cred_cb)
722                 wps->wps->cred_cb(wps->wps->cb_ctx, &cred);
723
724         return 0;
725 }
726
727
728 static enum wps_process_res wps_process_m2(struct wps_data *wps,
729                                            const struct wpabuf *msg,
730                                            struct wps_parse_attr *attr)
731 {
732         wpa_printf(MSG_DEBUG, "WPS: Received M2");
733
734         if (wps->state != RECV_M2) {
735                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
736                            "receiving M2", wps->state);
737                 return WPS_FAILURE;
738         }
739
740         if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
741             wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
742             wps_process_uuid_r(wps, attr->uuid_r) ||
743             wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
744             wps_process_authenticator(wps, attr->authenticator, msg))
745                 return WPS_FAILURE;
746
747         if (wps->authenticator && wps->wps->ap_setup_locked) {
748                 wpa_printf(MSG_DEBUG, "WPS: AP Setup is locked - refuse "
749                            "registration of a new Registrar");
750                 wps->state = SEND_WSC_NACK;
751                 return WPS_CONTINUE;
752         }
753
754         wps->state = SEND_M3;
755         return WPS_CONTINUE;
756 }
757
758
759 static enum wps_process_res wps_process_m2d(struct wps_data *wps,
760                                             struct wps_parse_attr *attr)
761 {
762         wpa_printf(MSG_DEBUG, "WPS: Received M2D");
763
764         if (wps->state != RECV_M2) {
765                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
766                            "receiving M2D", wps->state);
767                 return WPS_FAILURE;
768         }
769
770         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Manufacturer",
771                           attr->manufacturer, attr->manufacturer_len);
772         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Name",
773                           attr->model_name, attr->model_name_len);
774         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Number",
775                           attr->model_number, attr->model_number_len);
776         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Serial Number",
777                           attr->serial_number, attr->serial_number_len);
778         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Device Name",
779                           attr->dev_name, attr->dev_name_len);
780
781         /*
782          * TODO: notify monitor programs (cli/gui/etc.) of the M2D and provide
783          * user information about the registrar properties.
784          */
785
786         wps->state = RECEIVED_M2D;
787         return WPS_FAILURE;
788 }
789
790
791 static enum wps_process_res wps_process_m4(struct wps_data *wps,
792                                            const struct wpabuf *msg,
793                                            struct wps_parse_attr *attr)
794 {
795         struct wpabuf *decrypted;
796         struct wps_parse_attr eattr;
797
798         wpa_printf(MSG_DEBUG, "WPS: Received M4");
799
800         if (wps->state != RECV_M4) {
801                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
802                            "receiving M4", wps->state);
803                 return WPS_FAILURE;
804         }
805
806         if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
807             wps_process_authenticator(wps, attr->authenticator, msg) ||
808             wps_process_r_hash1(wps, attr->r_hash1) ||
809             wps_process_r_hash2(wps, attr->r_hash2))
810                 return WPS_FAILURE;
811
812         decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
813                                               attr->encr_settings_len);
814         if (decrypted == NULL) {
815                 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
816                            "Settings attribute");
817                 return WPS_FAILURE;
818         }
819
820         wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
821                    "attribute");
822         if (wps_parse_msg(decrypted, &eattr) < 0 ||
823             wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
824             wps_process_r_snonce1(wps, eattr.r_snonce1)) {
825                 wpabuf_free(decrypted);
826                 return WPS_FAILURE;
827         }
828         wpabuf_free(decrypted);
829
830         wps->state = SEND_M5;
831         return WPS_CONTINUE;
832 }
833
834
835 static enum wps_process_res wps_process_m6(struct wps_data *wps,
836                                            const struct wpabuf *msg,
837                                            struct wps_parse_attr *attr)
838 {
839         struct wpabuf *decrypted;
840         struct wps_parse_attr eattr;
841
842         wpa_printf(MSG_DEBUG, "WPS: Received M6");
843
844         if (wps->state != RECV_M6) {
845                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
846                            "receiving M6", wps->state);
847                 return WPS_FAILURE;
848         }
849
850         if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
851             wps_process_authenticator(wps, attr->authenticator, msg))
852                 return WPS_FAILURE;
853
854         decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
855                                               attr->encr_settings_len);
856         if (decrypted == NULL) {
857                 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
858                            "Settings attribute");
859                 return WPS_FAILURE;
860         }
861
862         wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
863                    "attribute");
864         if (wps_parse_msg(decrypted, &eattr) < 0 ||
865             wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
866             wps_process_r_snonce2(wps, eattr.r_snonce2)) {
867                 wpabuf_free(decrypted);
868                 return WPS_FAILURE;
869         }
870         wpabuf_free(decrypted);
871
872         wps->state = SEND_M7;
873         return WPS_CONTINUE;
874 }
875
876
877 static enum wps_process_res wps_process_m8(struct wps_data *wps,
878                                            const struct wpabuf *msg,
879                                            struct wps_parse_attr *attr)
880 {
881         struct wpabuf *decrypted;
882         struct wps_parse_attr eattr;
883
884         wpa_printf(MSG_DEBUG, "WPS: Received M8");
885
886         if (wps->state != RECV_M8) {
887                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
888                            "receiving M8", wps->state);
889                 return WPS_FAILURE;
890         }
891
892         if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
893             wps_process_authenticator(wps, attr->authenticator, msg))
894                 return WPS_FAILURE;
895
896         decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
897                                               attr->encr_settings_len);
898         if (decrypted == NULL) {
899                 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
900                            "Settings attribute");
901                 return WPS_FAILURE;
902         }
903
904         wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
905                    "attribute");
906         if (wps_parse_msg(decrypted, &eattr) < 0 ||
907             wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
908             wps_process_creds(wps, eattr.cred, eattr.cred_len,
909                               eattr.num_cred) ||
910             wps_process_ap_settings_e(wps, &eattr)) {
911                 wpabuf_free(decrypted);
912                 return WPS_FAILURE;
913         }
914         wpabuf_free(decrypted);
915
916         wps->state = WPS_MSG_DONE;
917         return WPS_CONTINUE;
918 }
919
920
921 static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
922                                                 const struct wpabuf *msg)
923 {
924         struct wps_parse_attr attr;
925         enum wps_process_res ret = WPS_CONTINUE;
926
927         wpa_printf(MSG_DEBUG, "WPS: Received WSC_MSG");
928
929         if (wps_parse_msg(msg, &attr) < 0)
930                 return WPS_FAILURE;
931
932         if (attr.version == NULL || *attr.version != WPS_VERSION) {
933                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
934                            attr.version ? *attr.version : 0);
935                 return WPS_FAILURE;
936         }
937
938         if (attr.enrollee_nonce == NULL ||
939             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
940                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
941                 return WPS_FAILURE;
942         }
943
944         if (attr.msg_type == NULL) {
945                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
946                 return WPS_FAILURE;
947         }
948
949         switch (*attr.msg_type) {
950         case WPS_M2:
951                 ret = wps_process_m2(wps, msg, &attr);
952                 break;
953         case WPS_M2D:
954                 ret = wps_process_m2d(wps, &attr);
955                 break;
956         case WPS_M4:
957                 ret = wps_process_m4(wps, msg, &attr);
958                 break;
959         case WPS_M6:
960                 ret = wps_process_m6(wps, msg, &attr);
961                 break;
962         case WPS_M8:
963                 ret = wps_process_m8(wps, msg, &attr);
964                 break;
965         default:
966                 wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
967                            *attr.msg_type);
968                 return WPS_FAILURE;
969         }
970
971         if (ret == WPS_CONTINUE) {
972                 /* Save a copy of the last message for Authenticator derivation
973                  */
974                 wpabuf_free(wps->last_msg);
975                 wps->last_msg = wpabuf_dup(msg);
976         }
977
978         return ret;
979 }
980
981
982 static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps,
983                                                 const struct wpabuf *msg)
984 {
985         struct wps_parse_attr attr;
986
987         wpa_printf(MSG_DEBUG, "WPS: Received WSC_ACK");
988
989         if (wps_parse_msg(msg, &attr) < 0)
990                 return WPS_FAILURE;
991
992         if (attr.version == NULL || *attr.version != WPS_VERSION) {
993                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
994                            attr.version ? *attr.version : 0);
995                 return WPS_FAILURE;
996         }
997
998         if (attr.msg_type == NULL) {
999                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
1000                 return WPS_FAILURE;
1001         }
1002
1003         if (*attr.msg_type != WPS_WSC_ACK) {
1004                 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
1005                            *attr.msg_type);
1006                 return WPS_FAILURE;
1007         }
1008
1009         if (attr.registrar_nonce == NULL ||
1010             os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
1011         {
1012                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
1013                 return WPS_FAILURE;
1014         }
1015
1016         if (attr.enrollee_nonce == NULL ||
1017             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
1018                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
1019                 return WPS_FAILURE;
1020         }
1021
1022         if (wps->state == RECV_ACK && wps->authenticator) {
1023                 wpa_printf(MSG_DEBUG, "WPS: External Registrar registration "
1024                            "completed successfully");
1025                 wps->state = WPS_FINISHED;
1026                 return WPS_DONE;
1027         }
1028
1029         return WPS_FAILURE;
1030 }
1031
1032
1033 static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
1034                                                  const struct wpabuf *msg)
1035 {
1036         struct wps_parse_attr attr;
1037
1038         wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK");
1039
1040         if (wps_parse_msg(msg, &attr) < 0)
1041                 return WPS_FAILURE;
1042
1043         if (attr.version == NULL || *attr.version != WPS_VERSION) {
1044                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
1045                            attr.version ? *attr.version : 0);
1046                 return WPS_FAILURE;
1047         }
1048
1049         if (attr.msg_type == NULL) {
1050                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
1051                 return WPS_FAILURE;
1052         }
1053
1054         if (*attr.msg_type != WPS_WSC_NACK) {
1055                 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
1056                            *attr.msg_type);
1057                 return WPS_FAILURE;
1058         }
1059
1060         if (attr.registrar_nonce == NULL ||
1061             os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
1062         {
1063                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
1064                 wpa_hexdump(MSG_DEBUG, "WPS: Received Registrar Nonce",
1065                             attr.registrar_nonce, WPS_NONCE_LEN);
1066                 wpa_hexdump(MSG_DEBUG, "WPS: Expected Registrar Nonce",
1067                             wps->nonce_r, WPS_NONCE_LEN);
1068                 return WPS_FAILURE;
1069         }
1070
1071         if (attr.enrollee_nonce == NULL ||
1072             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
1073                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
1074                 wpa_hexdump(MSG_DEBUG, "WPS: Received Enrollee Nonce",
1075                             attr.enrollee_nonce, WPS_NONCE_LEN);
1076                 wpa_hexdump(MSG_DEBUG, "WPS: Expected Enrollee Nonce",
1077                             wps->nonce_e, WPS_NONCE_LEN);
1078                 return WPS_FAILURE;
1079         }
1080
1081         if (attr.config_error == NULL) {
1082                 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error attribute "
1083                            "in WSC_NACK");
1084                 return WPS_FAILURE;
1085         }
1086
1087         wpa_printf(MSG_DEBUG, "WPS: Enrollee terminated negotiation with "
1088                    "Configuration Error %d", WPA_GET_BE16(attr.config_error));
1089
1090         return WPS_FAILURE;
1091 }
1092
1093
1094 enum wps_process_res wps_enrollee_process_msg(struct wps_data *wps, u8 op_code,
1095                                               const struct wpabuf *msg)
1096 {
1097
1098         wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu "
1099                    "op_code=%d)",
1100                    (unsigned long) wpabuf_len(msg), op_code);
1101
1102         switch (op_code) {
1103         case WSC_MSG:
1104                 return wps_process_wsc_msg(wps, msg);
1105         case WSC_ACK:
1106                 return wps_process_wsc_ack(wps, msg);
1107         case WSC_NACK:
1108                 return wps_process_wsc_nack(wps, msg);
1109         default:
1110                 wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code);
1111                 return WPS_FAILURE;
1112         }
1113 }
1114
1115
1116 struct wpabuf * wps_enrollee_build_assoc_req_ie(void)
1117 {
1118         struct wpabuf *ie;
1119         u8 *len;
1120
1121         wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for (Re)Association "
1122                    "Request");
1123         ie = wpabuf_alloc(100);
1124         if (ie == NULL)
1125                 return NULL;
1126
1127         wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
1128         len = wpabuf_put(ie, 1);
1129         wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
1130
1131         if (wps_build_version(ie) ||
1132             wps_build_req_type(ie, WPS_REQ_ENROLLEE)) {
1133                 wpabuf_free(ie);
1134                 return NULL;
1135         }
1136
1137         *len = wpabuf_len(ie) - 2;
1138
1139         return ie;
1140 }
1141
1142
1143 struct wpabuf * wps_enrollee_build_probe_req_ie(int pbc, const u8 *uuid)
1144 {
1145         struct wpabuf *ie;
1146         u8 *len;
1147         u16 methods;
1148         struct wps_device_data dev;
1149
1150         wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for Probe Request");
1151
1152         /* TODO: get device data from caller */
1153         os_memset(&dev, 0, sizeof(dev));
1154         dev.categ = WPS_DEV_COMPUTER;
1155         dev.oui = WPS_DEV_OUI_WFA;
1156         dev.sub_categ = WPS_DEV_COMPUTER_PC;
1157
1158         ie = wpabuf_alloc(200);
1159         if (ie == NULL)
1160                 return NULL;
1161
1162         wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
1163         len = wpabuf_put(ie, 1);
1164         wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
1165
1166         if (pbc)
1167                 methods = WPS_CONFIG_PUSHBUTTON;
1168         else
1169                 methods = WPS_CONFIG_LABEL | WPS_CONFIG_DISPLAY |
1170                         WPS_CONFIG_KEYPAD;
1171
1172         if (wps_build_version(ie) ||
1173             wps_build_req_type(ie, WPS_REQ_ENROLLEE) ||
1174             wps_build_config_methods(ie, methods) ||
1175             wps_build_uuid_e(ie, uuid) ||
1176             wps_build_primary_dev_type(&dev, ie) ||
1177             wps_build_rf_bands(NULL, ie) ||
1178             wps_build_assoc_state(NULL, ie) ||
1179             wps_build_config_error(NULL, ie) ||
1180             wps_build_dev_password_id(ie, pbc ? DEV_PW_PUSHBUTTON :
1181                                       DEV_PW_DEFAULT)) {
1182                 wpabuf_free(ie);
1183                 return NULL;
1184         }
1185
1186         *len = wpabuf_len(ie) - 2;
1187
1188         return ie;
1189 }