1/*
2 * DPP authentication exchange
3 * Copyright (c) 2017, Qualcomm Atheros, Inc.
4 * Copyright (c) 2018-2020, The Linux Foundation
5 *
6 * This software may be distributed under the terms of the BSD license.
7 * See README for more details.
8 */
9
10#include "utils/includes.h"
11
12#include "utils/common.h"
13#include "common/ieee802_11_common.h"
14#include "common/wpa_ctrl.h"
15#include "crypto/aes.h"
16#include "crypto/aes_siv.h"
17#include "crypto/random.h"
18#include "dpp.h"
19#include "dpp_i.h"
20
21
22#ifdef CONFIG_TESTING_OPTIONS
23u8 dpp_protocol_key_override[600];
24size_t dpp_protocol_key_override_len = 0;
25u8 dpp_nonce_override[DPP_MAX_NONCE_LEN];
26size_t dpp_nonce_override_len = 0;
27#endif /* CONFIG_TESTING_OPTIONS */
28
29
30static void dpp_build_attr_i_bootstrap_key_hash(struct wpabuf *msg,
31						const u8 *hash)
32{
33	if (hash) {
34		wpa_printf(MSG_DEBUG, "DPP: I-Bootstrap Key Hash");
35		wpabuf_put_le16(msg, DPP_ATTR_I_BOOTSTRAP_KEY_HASH);
36		wpabuf_put_le16(msg, SHA256_MAC_LEN);
37		wpabuf_put_data(msg, hash, SHA256_MAC_LEN);
38	}
39}
40
41
42static void dpp_auth_success(struct dpp_authentication *auth)
43{
44	wpa_printf(MSG_DEBUG,
45		   "DPP: Authentication success - clear temporary keys");
46	os_memset(auth->Mx, 0, sizeof(auth->Mx));
47	auth->Mx_len = 0;
48	os_memset(auth->Nx, 0, sizeof(auth->Nx));
49	auth->Nx_len = 0;
50	os_memset(auth->Lx, 0, sizeof(auth->Lx));
51	auth->Lx_len = 0;
52	os_memset(auth->k1, 0, sizeof(auth->k1));
53	os_memset(auth->k2, 0, sizeof(auth->k2));
54
55	auth->auth_success = 1;
56}
57
58
59static struct wpabuf * dpp_auth_build_req(struct dpp_authentication *auth,
60					  const struct wpabuf *pi,
61					  size_t nonce_len,
62					  const u8 *r_pubkey_hash,
63					  const u8 *i_pubkey_hash,
64					  unsigned int neg_freq)
65{
66	struct wpabuf *msg;
67	u8 clear[4 + DPP_MAX_NONCE_LEN + 4 + 1];
68	u8 wrapped_data[4 + DPP_MAX_NONCE_LEN + 4 + 1 + AES_BLOCK_SIZE];
69	u8 *pos;
70	const u8 *addr[2];
71	size_t len[2], siv_len, attr_len;
72	u8 *attr_start, *attr_end;
73
74	/* Build DPP Authentication Request frame attributes */
75	attr_len = 2 * (4 + SHA256_MAC_LEN) + 4 + (pi ? wpabuf_len(pi) : 0) +
76		4 + sizeof(wrapped_data);
77	if (neg_freq > 0)
78		attr_len += 4 + 2;
79#ifdef CONFIG_DPP2
80	attr_len += 5;
81#endif /* CONFIG_DPP2 */
82#ifdef CONFIG_TESTING_OPTIONS
83	if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_REQ)
84		attr_len += 5;
85#endif /* CONFIG_TESTING_OPTIONS */
86	msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_REQ, attr_len);
87	if (!msg)
88		return NULL;
89
90	attr_start = wpabuf_put(msg, 0);
91
92	/* Responder Bootstrapping Key Hash */
93	dpp_build_attr_r_bootstrap_key_hash(msg, r_pubkey_hash);
94
95	/* Initiator Bootstrapping Key Hash */
96	dpp_build_attr_i_bootstrap_key_hash(msg, i_pubkey_hash);
97
98	/* Initiator Protocol Key */
99	if (pi) {
100		wpabuf_put_le16(msg, DPP_ATTR_I_PROTOCOL_KEY);
101		wpabuf_put_le16(msg, wpabuf_len(pi));
102		wpabuf_put_buf(msg, pi);
103	}
104
105	/* Channel */
106	if (neg_freq > 0) {
107		u8 op_class, channel;
108
109		if (ieee80211_freq_to_channel_ext(neg_freq, 0, 0, &op_class,
110						  &channel) ==
111		    NUM_HOSTAPD_MODES) {
112			wpa_printf(MSG_INFO,
113				   "DPP: Unsupported negotiation frequency request: %d",
114				   neg_freq);
115			wpabuf_free(msg);
116			return NULL;
117		}
118		wpabuf_put_le16(msg, DPP_ATTR_CHANNEL);
119		wpabuf_put_le16(msg, 2);
120		wpabuf_put_u8(msg, op_class);
121		wpabuf_put_u8(msg, channel);
122	}
123
124#ifdef CONFIG_DPP2
125	/* Protocol Version */
126	if (DPP_VERSION > 1) {
127		wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
128		wpabuf_put_le16(msg, 1);
129		wpabuf_put_u8(msg, DPP_VERSION);
130	}
131#endif /* CONFIG_DPP2 */
132
133#ifdef CONFIG_TESTING_OPTIONS
134	if (dpp_test == DPP_TEST_NO_WRAPPED_DATA_AUTH_REQ) {
135		wpa_printf(MSG_INFO, "DPP: TESTING - no Wrapped Data");
136		goto skip_wrapped_data;
137	}
138#endif /* CONFIG_TESTING_OPTIONS */
139
140	/* Wrapped data ({I-nonce, I-capabilities}k1) */
141	pos = clear;
142
143#ifdef CONFIG_TESTING_OPTIONS
144	if (dpp_test == DPP_TEST_NO_I_NONCE_AUTH_REQ) {
145		wpa_printf(MSG_INFO, "DPP: TESTING - no I-nonce");
146		goto skip_i_nonce;
147	}
148	if (dpp_test == DPP_TEST_INVALID_I_NONCE_AUTH_REQ) {
149		wpa_printf(MSG_INFO, "DPP: TESTING - invalid I-nonce");
150		WPA_PUT_LE16(pos, DPP_ATTR_I_NONCE);
151		pos += 2;
152		WPA_PUT_LE16(pos, nonce_len - 1);
153		pos += 2;
154		os_memcpy(pos, auth->i_nonce, nonce_len - 1);
155		pos += nonce_len - 1;
156		goto skip_i_nonce;
157	}
158#endif /* CONFIG_TESTING_OPTIONS */
159
160	/* I-nonce */
161	WPA_PUT_LE16(pos, DPP_ATTR_I_NONCE);
162	pos += 2;
163	WPA_PUT_LE16(pos, nonce_len);
164	pos += 2;
165	os_memcpy(pos, auth->i_nonce, nonce_len);
166	pos += nonce_len;
167
168#ifdef CONFIG_TESTING_OPTIONS
169skip_i_nonce:
170	if (dpp_test == DPP_TEST_NO_I_CAPAB_AUTH_REQ) {
171		wpa_printf(MSG_INFO, "DPP: TESTING - no I-capab");
172		goto skip_i_capab;
173	}
174#endif /* CONFIG_TESTING_OPTIONS */
175
176	/* I-capabilities */
177	WPA_PUT_LE16(pos, DPP_ATTR_I_CAPABILITIES);
178	pos += 2;
179	WPA_PUT_LE16(pos, 1);
180	pos += 2;
181	auth->i_capab = auth->allowed_roles;
182	*pos++ = auth->i_capab;
183#ifdef CONFIG_TESTING_OPTIONS
184	if (dpp_test == DPP_TEST_ZERO_I_CAPAB) {
185		wpa_printf(MSG_INFO, "DPP: TESTING - zero I-capabilities");
186		pos[-1] = 0;
187	}
188skip_i_capab:
189#endif /* CONFIG_TESTING_OPTIONS */
190
191	attr_end = wpabuf_put(msg, 0);
192
193	/* OUI, OUI type, Crypto Suite, DPP frame type */
194	addr[0] = wpabuf_head_u8(msg) + 2;
195	len[0] = 3 + 1 + 1 + 1;
196	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
197
198	/* Attributes before Wrapped Data */
199	addr[1] = attr_start;
200	len[1] = attr_end - attr_start;
201	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
202
203	siv_len = pos - clear;
204	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", clear, siv_len);
205	if (aes_siv_encrypt(auth->k1, auth->curve->hash_len, clear, siv_len,
206			    2, addr, len, wrapped_data) < 0) {
207		wpabuf_free(msg);
208		return NULL;
209	}
210	siv_len += AES_BLOCK_SIZE;
211	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
212		    wrapped_data, siv_len);
213
214	wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
215	wpabuf_put_le16(msg, siv_len);
216	wpabuf_put_data(msg, wrapped_data, siv_len);
217
218#ifdef CONFIG_TESTING_OPTIONS
219	if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_REQ) {
220		wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
221		dpp_build_attr_status(msg, DPP_STATUS_OK);
222	}
223skip_wrapped_data:
224#endif /* CONFIG_TESTING_OPTIONS */
225
226	wpa_hexdump_buf(MSG_DEBUG,
227			"DPP: Authentication Request frame attributes", msg);
228
229	return msg;
230}
231
232
233static struct wpabuf * dpp_auth_build_resp(struct dpp_authentication *auth,
234					   enum dpp_status_error status,
235					   const struct wpabuf *pr,
236					   size_t nonce_len,
237					   const u8 *r_pubkey_hash,
238					   const u8 *i_pubkey_hash,
239					   const u8 *r_nonce, const u8 *i_nonce,
240					   const u8 *wrapped_r_auth,
241					   size_t wrapped_r_auth_len,
242					   const u8 *siv_key)
243{
244	struct wpabuf *msg;
245#define DPP_AUTH_RESP_CLEAR_LEN 2 * (4 + DPP_MAX_NONCE_LEN) + 4 + 1 + \
246		4 + 4 + DPP_MAX_HASH_LEN + AES_BLOCK_SIZE
247	u8 clear[DPP_AUTH_RESP_CLEAR_LEN];
248	u8 wrapped_data[DPP_AUTH_RESP_CLEAR_LEN + AES_BLOCK_SIZE];
249	const u8 *addr[2];
250	size_t len[2], siv_len, attr_len;
251	u8 *attr_start, *attr_end, *pos;
252
253	auth->waiting_auth_conf = 1;
254	auth->auth_resp_status = status;
255	auth->auth_resp_tries = 0;
256
257	/* Build DPP Authentication Response frame attributes */
258	attr_len = 4 + 1 + 2 * (4 + SHA256_MAC_LEN) +
259		4 + (pr ? wpabuf_len(pr) : 0) + 4 + sizeof(wrapped_data);
260#ifdef CONFIG_DPP2
261	attr_len += 5;
262#endif /* CONFIG_DPP2 */
263#ifdef CONFIG_TESTING_OPTIONS
264	if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_RESP)
265		attr_len += 5;
266#endif /* CONFIG_TESTING_OPTIONS */
267	msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_RESP, attr_len);
268	if (!msg)
269		return NULL;
270
271	attr_start = wpabuf_put(msg, 0);
272
273	/* DPP Status */
274	if (status != 255)
275		dpp_build_attr_status(msg, status);
276
277	/* Responder Bootstrapping Key Hash */
278	dpp_build_attr_r_bootstrap_key_hash(msg, r_pubkey_hash);
279
280	/* Initiator Bootstrapping Key Hash (mutual authentication) */
281	dpp_build_attr_i_bootstrap_key_hash(msg, i_pubkey_hash);
282
283	/* Responder Protocol Key */
284	if (pr) {
285		wpabuf_put_le16(msg, DPP_ATTR_R_PROTOCOL_KEY);
286		wpabuf_put_le16(msg, wpabuf_len(pr));
287		wpabuf_put_buf(msg, pr);
288	}
289
290#ifdef CONFIG_DPP2
291	/* Protocol Version */
292	if (auth->peer_version >= 2) {
293		wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
294		wpabuf_put_le16(msg, 1);
295		wpabuf_put_u8(msg, DPP_VERSION);
296	}
297#endif /* CONFIG_DPP2 */
298
299	attr_end = wpabuf_put(msg, 0);
300
301#ifdef CONFIG_TESTING_OPTIONS
302	if (dpp_test == DPP_TEST_NO_WRAPPED_DATA_AUTH_RESP) {
303		wpa_printf(MSG_INFO, "DPP: TESTING - no Wrapped Data");
304		goto skip_wrapped_data;
305	}
306#endif /* CONFIG_TESTING_OPTIONS */
307
308	/* Wrapped data ({R-nonce, I-nonce, R-capabilities, {R-auth}ke}k2) */
309	pos = clear;
310
311	if (r_nonce) {
312		/* R-nonce */
313		WPA_PUT_LE16(pos, DPP_ATTR_R_NONCE);
314		pos += 2;
315		WPA_PUT_LE16(pos, nonce_len);
316		pos += 2;
317		os_memcpy(pos, r_nonce, nonce_len);
318		pos += nonce_len;
319	}
320
321	if (i_nonce) {
322		/* I-nonce */
323		WPA_PUT_LE16(pos, DPP_ATTR_I_NONCE);
324		pos += 2;
325		WPA_PUT_LE16(pos, nonce_len);
326		pos += 2;
327		os_memcpy(pos, i_nonce, nonce_len);
328#ifdef CONFIG_TESTING_OPTIONS
329		if (dpp_test == DPP_TEST_I_NONCE_MISMATCH_AUTH_RESP) {
330			wpa_printf(MSG_INFO, "DPP: TESTING - I-nonce mismatch");
331			pos[nonce_len / 2] ^= 0x01;
332		}
333#endif /* CONFIG_TESTING_OPTIONS */
334		pos += nonce_len;
335	}
336
337#ifdef CONFIG_TESTING_OPTIONS
338	if (dpp_test == DPP_TEST_NO_R_CAPAB_AUTH_RESP) {
339		wpa_printf(MSG_INFO, "DPP: TESTING - no R-capab");
340		goto skip_r_capab;
341	}
342#endif /* CONFIG_TESTING_OPTIONS */
343
344	/* R-capabilities */
345	WPA_PUT_LE16(pos, DPP_ATTR_R_CAPABILITIES);
346	pos += 2;
347	WPA_PUT_LE16(pos, 1);
348	pos += 2;
349	auth->r_capab = auth->configurator ? DPP_CAPAB_CONFIGURATOR :
350		DPP_CAPAB_ENROLLEE;
351	*pos++ = auth->r_capab;
352#ifdef CONFIG_TESTING_OPTIONS
353	if (dpp_test == DPP_TEST_ZERO_R_CAPAB) {
354		wpa_printf(MSG_INFO, "DPP: TESTING - zero R-capabilities");
355		pos[-1] = 0;
356	} else if (dpp_test == DPP_TEST_INCOMPATIBLE_R_CAPAB_AUTH_RESP) {
357		wpa_printf(MSG_INFO,
358			   "DPP: TESTING - incompatible R-capabilities");
359		if ((auth->i_capab & DPP_CAPAB_ROLE_MASK) ==
360		    (DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE))
361			pos[-1] = 0;
362		else
363			pos[-1] = auth->configurator ? DPP_CAPAB_ENROLLEE :
364				DPP_CAPAB_CONFIGURATOR;
365	}
366skip_r_capab:
367#endif /* CONFIG_TESTING_OPTIONS */
368
369	if (wrapped_r_auth) {
370		/* {R-auth}ke */
371		WPA_PUT_LE16(pos, DPP_ATTR_WRAPPED_DATA);
372		pos += 2;
373		WPA_PUT_LE16(pos, wrapped_r_auth_len);
374		pos += 2;
375		os_memcpy(pos, wrapped_r_auth, wrapped_r_auth_len);
376		pos += wrapped_r_auth_len;
377	}
378
379	/* OUI, OUI type, Crypto Suite, DPP frame type */
380	addr[0] = wpabuf_head_u8(msg) + 2;
381	len[0] = 3 + 1 + 1 + 1;
382	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
383
384	/* Attributes before Wrapped Data */
385	addr[1] = attr_start;
386	len[1] = attr_end - attr_start;
387	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
388
389	siv_len = pos - clear;
390	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", clear, siv_len);
391	if (aes_siv_encrypt(siv_key, auth->curve->hash_len, clear, siv_len,
392			    2, addr, len, wrapped_data) < 0) {
393		wpabuf_free(msg);
394		return NULL;
395	}
396	siv_len += AES_BLOCK_SIZE;
397	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
398		    wrapped_data, siv_len);
399
400	wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
401	wpabuf_put_le16(msg, siv_len);
402	wpabuf_put_data(msg, wrapped_data, siv_len);
403
404#ifdef CONFIG_TESTING_OPTIONS
405	if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_RESP) {
406		wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
407		dpp_build_attr_status(msg, DPP_STATUS_OK);
408	}
409skip_wrapped_data:
410#endif /* CONFIG_TESTING_OPTIONS */
411
412	wpa_hexdump_buf(MSG_DEBUG,
413			"DPP: Authentication Response frame attributes", msg);
414	return msg;
415}
416
417
418static int dpp_auth_build_resp_ok(struct dpp_authentication *auth)
419{
420	size_t nonce_len;
421	size_t secret_len;
422	struct wpabuf *msg, *pr = NULL;
423	u8 r_auth[4 + DPP_MAX_HASH_LEN];
424	u8 wrapped_r_auth[4 + DPP_MAX_HASH_LEN + AES_BLOCK_SIZE], *w_r_auth;
425	size_t wrapped_r_auth_len;
426	int ret = -1;
427	const u8 *r_pubkey_hash, *i_pubkey_hash, *r_nonce, *i_nonce;
428	enum dpp_status_error status = DPP_STATUS_OK;
429#ifdef CONFIG_TESTING_OPTIONS
430	u8 test_hash[SHA256_MAC_LEN];
431#endif /* CONFIG_TESTING_OPTIONS */
432
433	wpa_printf(MSG_DEBUG, "DPP: Build Authentication Response");
434	if (!auth->own_bi)
435		return -1;
436
437#ifdef CONFIG_TESTING_OPTIONS
438	if (dpp_nonce_override_len > 0) {
439		wpa_printf(MSG_INFO, "DPP: TESTING - override R-nonce");
440		nonce_len = dpp_nonce_override_len;
441		os_memcpy(auth->r_nonce, dpp_nonce_override, nonce_len);
442	} else {
443		nonce_len = auth->curve->nonce_len;
444		if (random_get_bytes(auth->r_nonce, nonce_len)) {
445			wpa_printf(MSG_ERROR,
446				   "DPP: Failed to generate R-nonce");
447			goto fail;
448		}
449	}
450#else /* CONFIG_TESTING_OPTIONS */
451	nonce_len = auth->curve->nonce_len;
452	if (random_get_bytes(auth->r_nonce, nonce_len)) {
453		wpa_printf(MSG_ERROR, "DPP: Failed to generate R-nonce");
454		goto fail;
455	}
456#endif /* CONFIG_TESTING_OPTIONS */
457	wpa_hexdump(MSG_DEBUG, "DPP: R-nonce", auth->r_nonce, nonce_len);
458
459	crypto_ec_key_deinit(auth->own_protocol_key);
460#ifdef CONFIG_TESTING_OPTIONS
461	if (dpp_protocol_key_override_len) {
462		const struct dpp_curve_params *tmp_curve;
463
464		wpa_printf(MSG_INFO,
465			   "DPP: TESTING - override protocol key");
466		auth->own_protocol_key = dpp_set_keypair(
467			&tmp_curve, dpp_protocol_key_override,
468			dpp_protocol_key_override_len);
469	} else {
470		auth->own_protocol_key = dpp_gen_keypair(auth->curve);
471	}
472#else /* CONFIG_TESTING_OPTIONS */
473	auth->own_protocol_key = dpp_gen_keypair(auth->curve);
474#endif /* CONFIG_TESTING_OPTIONS */
475	if (!auth->own_protocol_key)
476		goto fail;
477
478	pr = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0);
479	if (!pr)
480		goto fail;
481
482	/* ECDH: N = pR * PI */
483	if (dpp_ecdh(auth->own_protocol_key, auth->peer_protocol_key,
484		     auth->Nx, &secret_len) < 0)
485		goto fail;
486
487	wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (N.x)",
488			auth->Nx, auth->secret_len);
489	auth->Nx_len = auth->secret_len;
490
491	if (dpp_derive_k2(auth->Nx, auth->secret_len, auth->k2,
492			  auth->curve->hash_len) < 0)
493		goto fail;
494
495	if (auth->own_bi && auth->peer_bi) {
496		/* Mutual authentication */
497		if (dpp_auth_derive_l_responder(auth) < 0)
498			goto fail;
499	}
500
501	if (dpp_derive_bk_ke(auth) < 0)
502		goto fail;
503
504	/* R-auth = H(I-nonce | R-nonce | PI.x | PR.x | [BI.x |] BR.x | 0) */
505	WPA_PUT_LE16(r_auth, DPP_ATTR_R_AUTH_TAG);
506	WPA_PUT_LE16(&r_auth[2], auth->curve->hash_len);
507	if (dpp_gen_r_auth(auth, r_auth + 4) < 0)
508		goto fail;
509#ifdef CONFIG_TESTING_OPTIONS
510	if (dpp_test == DPP_TEST_R_AUTH_MISMATCH_AUTH_RESP) {
511		wpa_printf(MSG_INFO, "DPP: TESTING - R-auth mismatch");
512		r_auth[4 + auth->curve->hash_len / 2] ^= 0x01;
513	}
514#endif /* CONFIG_TESTING_OPTIONS */
515	if (aes_siv_encrypt(auth->ke, auth->curve->hash_len,
516			    r_auth, 4 + auth->curve->hash_len,
517			    0, NULL, NULL, wrapped_r_auth) < 0)
518		goto fail;
519	wrapped_r_auth_len = 4 + auth->curve->hash_len + AES_BLOCK_SIZE;
520	wpa_hexdump(MSG_DEBUG, "DPP: {R-auth}ke",
521		    wrapped_r_auth, wrapped_r_auth_len);
522	w_r_auth = wrapped_r_auth;
523
524	r_pubkey_hash = auth->own_bi->pubkey_hash;
525	if (auth->peer_bi)
526		i_pubkey_hash = auth->peer_bi->pubkey_hash;
527	else
528		i_pubkey_hash = NULL;
529
530	i_nonce = auth->i_nonce;
531	r_nonce = auth->r_nonce;
532
533#ifdef CONFIG_TESTING_OPTIONS
534	if (dpp_test == DPP_TEST_NO_R_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
535		wpa_printf(MSG_INFO, "DPP: TESTING - no R-Bootstrap Key Hash");
536		r_pubkey_hash = NULL;
537	} else if (dpp_test ==
538		   DPP_TEST_INVALID_R_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
539		wpa_printf(MSG_INFO,
540			   "DPP: TESTING - invalid R-Bootstrap Key Hash");
541		os_memcpy(test_hash, r_pubkey_hash, SHA256_MAC_LEN);
542		test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
543		r_pubkey_hash = test_hash;
544	} else if (dpp_test == DPP_TEST_NO_I_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
545		wpa_printf(MSG_INFO, "DPP: TESTING - no I-Bootstrap Key Hash");
546		i_pubkey_hash = NULL;
547	} else if (dpp_test ==
548		   DPP_TEST_INVALID_I_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
549		wpa_printf(MSG_INFO,
550			   "DPP: TESTING - invalid I-Bootstrap Key Hash");
551		if (i_pubkey_hash)
552			os_memcpy(test_hash, i_pubkey_hash, SHA256_MAC_LEN);
553		else
554			os_memset(test_hash, 0, SHA256_MAC_LEN);
555		test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
556		i_pubkey_hash = test_hash;
557	} else if (dpp_test == DPP_TEST_NO_R_PROTO_KEY_AUTH_RESP) {
558		wpa_printf(MSG_INFO, "DPP: TESTING - no R-Proto Key");
559		wpabuf_free(pr);
560		pr = NULL;
561	} else if (dpp_test == DPP_TEST_INVALID_R_PROTO_KEY_AUTH_RESP) {
562		wpa_printf(MSG_INFO, "DPP: TESTING - invalid R-Proto Key");
563		wpabuf_free(pr);
564		pr = wpabuf_alloc(2 * auth->curve->prime_len);
565		if (!pr || dpp_test_gen_invalid_key(pr, auth->curve) < 0)
566			goto fail;
567	} else if (dpp_test == DPP_TEST_NO_R_AUTH_AUTH_RESP) {
568		wpa_printf(MSG_INFO, "DPP: TESTING - no R-Auth");
569		w_r_auth = NULL;
570		wrapped_r_auth_len = 0;
571	} else if (dpp_test == DPP_TEST_NO_STATUS_AUTH_RESP) {
572		wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
573		status = 255;
574	} else if (dpp_test == DPP_TEST_INVALID_STATUS_AUTH_RESP) {
575		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status");
576		status = 254;
577	} else if (dpp_test == DPP_TEST_NO_R_NONCE_AUTH_RESP) {
578		wpa_printf(MSG_INFO, "DPP: TESTING - no R-nonce");
579		r_nonce = NULL;
580	} else if (dpp_test == DPP_TEST_NO_I_NONCE_AUTH_RESP) {
581		wpa_printf(MSG_INFO, "DPP: TESTING - no I-nonce");
582		i_nonce = NULL;
583	}
584#endif /* CONFIG_TESTING_OPTIONS */
585
586	msg = dpp_auth_build_resp(auth, status, pr, nonce_len,
587				  r_pubkey_hash, i_pubkey_hash,
588				  r_nonce, i_nonce,
589				  w_r_auth, wrapped_r_auth_len,
590				  auth->k2);
591	if (!msg)
592		goto fail;
593	wpabuf_free(auth->resp_msg);
594	auth->resp_msg = msg;
595	ret = 0;
596fail:
597	wpabuf_free(pr);
598	return ret;
599}
600
601
602static int dpp_auth_build_resp_status(struct dpp_authentication *auth,
603				      enum dpp_status_error status)
604{
605	struct wpabuf *msg;
606	const u8 *r_pubkey_hash, *i_pubkey_hash, *i_nonce;
607#ifdef CONFIG_TESTING_OPTIONS
608	u8 test_hash[SHA256_MAC_LEN];
609#endif /* CONFIG_TESTING_OPTIONS */
610
611	if (!auth->own_bi)
612		return -1;
613	wpa_printf(MSG_DEBUG, "DPP: Build Authentication Response");
614
615	r_pubkey_hash = auth->own_bi->pubkey_hash;
616	if (auth->peer_bi)
617		i_pubkey_hash = auth->peer_bi->pubkey_hash;
618	else
619		i_pubkey_hash = NULL;
620
621	i_nonce = auth->i_nonce;
622
623#ifdef CONFIG_TESTING_OPTIONS
624	if (dpp_test == DPP_TEST_NO_R_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
625		wpa_printf(MSG_INFO, "DPP: TESTING - no R-Bootstrap Key Hash");
626		r_pubkey_hash = NULL;
627	} else if (dpp_test ==
628		   DPP_TEST_INVALID_R_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
629		wpa_printf(MSG_INFO,
630			   "DPP: TESTING - invalid R-Bootstrap Key Hash");
631		os_memcpy(test_hash, r_pubkey_hash, SHA256_MAC_LEN);
632		test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
633		r_pubkey_hash = test_hash;
634	} else if (dpp_test == DPP_TEST_NO_I_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
635		wpa_printf(MSG_INFO, "DPP: TESTING - no I-Bootstrap Key Hash");
636		i_pubkey_hash = NULL;
637	} else if (dpp_test ==
638		   DPP_TEST_INVALID_I_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
639		wpa_printf(MSG_INFO,
640			   "DPP: TESTING - invalid I-Bootstrap Key Hash");
641		if (i_pubkey_hash)
642			os_memcpy(test_hash, i_pubkey_hash, SHA256_MAC_LEN);
643		else
644			os_memset(test_hash, 0, SHA256_MAC_LEN);
645		test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
646		i_pubkey_hash = test_hash;
647	} else if (dpp_test == DPP_TEST_NO_STATUS_AUTH_RESP) {
648		wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
649		status = 255;
650	} else if (dpp_test == DPP_TEST_NO_I_NONCE_AUTH_RESP) {
651		wpa_printf(MSG_INFO, "DPP: TESTING - no I-nonce");
652		i_nonce = NULL;
653	}
654#endif /* CONFIG_TESTING_OPTIONS */
655
656	msg = dpp_auth_build_resp(auth, status, NULL, auth->curve->nonce_len,
657				  r_pubkey_hash, i_pubkey_hash,
658				  NULL, i_nonce, NULL, 0, auth->k1);
659	if (!msg)
660		return -1;
661	wpabuf_free(auth->resp_msg);
662	auth->resp_msg = msg;
663	return 0;
664}
665
666
667struct dpp_authentication *
668dpp_auth_req_rx(struct dpp_global *dpp, void *msg_ctx, u8 dpp_allowed_roles,
669		int qr_mutual, struct dpp_bootstrap_info *peer_bi,
670		struct dpp_bootstrap_info *own_bi,
671		unsigned int freq, const u8 *hdr, const u8 *attr_start,
672		size_t attr_len)
673{
674	struct crypto_ec_key *pi = NULL;
675	size_t secret_len;
676	const u8 *addr[2];
677	size_t len[2];
678	u8 *unwrapped = NULL;
679	size_t unwrapped_len = 0;
680	const u8 *wrapped_data, *i_proto, *i_nonce, *i_capab, *i_bootstrap,
681		*channel;
682	u16 wrapped_data_len, i_proto_len, i_nonce_len, i_capab_len,
683		i_bootstrap_len, channel_len;
684	struct dpp_authentication *auth = NULL;
685#ifdef CONFIG_DPP2
686	const u8 *version;
687	u16 version_len;
688#endif /* CONFIG_DPP2 */
689
690#ifdef CONFIG_TESTING_OPTIONS
691	if (dpp_test == DPP_TEST_STOP_AT_AUTH_REQ) {
692		wpa_printf(MSG_INFO,
693			   "DPP: TESTING - stop at Authentication Request");
694		return NULL;
695	}
696#endif /* CONFIG_TESTING_OPTIONS */
697
698	wrapped_data = dpp_get_attr(attr_start, attr_len, DPP_ATTR_WRAPPED_DATA,
699				    &wrapped_data_len);
700	if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) {
701		wpa_msg(msg_ctx, MSG_INFO, DPP_EVENT_FAIL
702			"Missing or invalid required Wrapped Data attribute");
703		return NULL;
704	}
705	wpa_hexdump(MSG_MSGDUMP, "DPP: Wrapped Data",
706		    wrapped_data, wrapped_data_len);
707	attr_len = wrapped_data - 4 - attr_start;
708
709	auth = dpp_alloc_auth(dpp, msg_ctx);
710	if (!auth)
711		goto fail;
712	if (peer_bi && peer_bi->configurator_params &&
713	    dpp_set_configurator(auth, peer_bi->configurator_params) < 0)
714		goto fail;
715	auth->peer_bi = peer_bi;
716	auth->own_bi = own_bi;
717	auth->curve = own_bi->curve;
718	auth->curr_freq = freq;
719
720	auth->peer_version = 1; /* default to the first version */
721#ifdef CONFIG_DPP2
722	version = dpp_get_attr(attr_start, attr_len, DPP_ATTR_PROTOCOL_VERSION,
723			       &version_len);
724	if (version && DPP_VERSION > 1) {
725		if (version_len < 1 || version[0] == 0) {
726			dpp_auth_fail(auth,
727				      "Invalid Protocol Version attribute");
728			goto fail;
729		}
730		auth->peer_version = version[0];
731		wpa_printf(MSG_DEBUG, "DPP: Peer protocol version %u",
732			   auth->peer_version);
733	}
734#endif /* CONFIG_DPP2 */
735
736	channel = dpp_get_attr(attr_start, attr_len, DPP_ATTR_CHANNEL,
737			       &channel_len);
738	if (channel) {
739		int neg_freq;
740
741		if (channel_len < 2) {
742			dpp_auth_fail(auth, "Too short Channel attribute");
743			goto fail;
744		}
745
746		neg_freq = ieee80211_chan_to_freq(NULL, channel[0], channel[1]);
747		wpa_printf(MSG_DEBUG,
748			   "DPP: Initiator requested different channel for negotiation: op_class=%u channel=%u --> freq=%d",
749			   channel[0], channel[1], neg_freq);
750		if (neg_freq < 0) {
751			dpp_auth_fail(auth,
752				      "Unsupported Channel attribute value");
753			goto fail;
754		}
755
756		if (auth->curr_freq != (unsigned int) neg_freq) {
757			wpa_printf(MSG_DEBUG,
758				   "DPP: Changing negotiation channel from %u MHz to %u MHz",
759				   freq, neg_freq);
760			auth->curr_freq = neg_freq;
761		}
762	}
763
764	i_proto = dpp_get_attr(attr_start, attr_len, DPP_ATTR_I_PROTOCOL_KEY,
765			       &i_proto_len);
766	if (!i_proto) {
767		dpp_auth_fail(auth,
768			      "Missing required Initiator Protocol Key attribute");
769		goto fail;
770	}
771	wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Protocol Key",
772		    i_proto, i_proto_len);
773
774	/* M = bR * PI */
775	pi = dpp_set_pubkey_point(own_bi->pubkey, i_proto, i_proto_len);
776	if (!pi) {
777		dpp_auth_fail(auth, "Invalid Initiator Protocol Key");
778		goto fail;
779	}
780	dpp_debug_print_key("Peer (Initiator) Protocol Key", pi);
781
782	if (dpp_ecdh(own_bi->pubkey, pi, auth->Mx, &secret_len) < 0)
783		goto fail;
784	auth->secret_len = secret_len;
785
786	wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (M.x)",
787			auth->Mx, auth->secret_len);
788	auth->Mx_len = auth->secret_len;
789
790	if (dpp_derive_k1(auth->Mx, auth->secret_len, auth->k1,
791			  auth->curve->hash_len) < 0)
792		goto fail;
793
794	addr[0] = hdr;
795	len[0] = DPP_HDR_LEN;
796	addr[1] = attr_start;
797	len[1] = attr_len;
798	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
799	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
800	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
801		    wrapped_data, wrapped_data_len);
802	unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
803	unwrapped = os_malloc(unwrapped_len);
804	if (!unwrapped)
805		goto fail;
806	if (aes_siv_decrypt(auth->k1, auth->curve->hash_len,
807			    wrapped_data, wrapped_data_len,
808			    2, addr, len, unwrapped) < 0) {
809		dpp_auth_fail(auth, "AES-SIV decryption failed");
810		goto fail;
811	}
812	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
813		    unwrapped, unwrapped_len);
814
815	if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
816		dpp_auth_fail(auth, "Invalid attribute in unwrapped data");
817		goto fail;
818	}
819
820	i_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_NONCE,
821			       &i_nonce_len);
822	if (!i_nonce || i_nonce_len != auth->curve->nonce_len) {
823		dpp_auth_fail(auth, "Missing or invalid I-nonce");
824		goto fail;
825	}
826	wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", i_nonce, i_nonce_len);
827	os_memcpy(auth->i_nonce, i_nonce, i_nonce_len);
828
829	i_capab = dpp_get_attr(unwrapped, unwrapped_len,
830			       DPP_ATTR_I_CAPABILITIES,
831			       &i_capab_len);
832	if (!i_capab || i_capab_len < 1) {
833		dpp_auth_fail(auth, "Missing or invalid I-capabilities");
834		goto fail;
835	}
836	auth->i_capab = i_capab[0];
837	wpa_printf(MSG_DEBUG, "DPP: I-capabilities: 0x%02x", auth->i_capab);
838
839	bin_clear_free(unwrapped, unwrapped_len);
840	unwrapped = NULL;
841
842	switch (auth->i_capab & DPP_CAPAB_ROLE_MASK) {
843	case DPP_CAPAB_ENROLLEE:
844		if (!(dpp_allowed_roles & DPP_CAPAB_CONFIGURATOR)) {
845			wpa_printf(MSG_DEBUG,
846				   "DPP: Local policy does not allow Configurator role");
847			goto not_compatible;
848		}
849		wpa_printf(MSG_DEBUG, "DPP: Acting as Configurator");
850		auth->configurator = 1;
851		break;
852	case DPP_CAPAB_CONFIGURATOR:
853		if (!(dpp_allowed_roles & DPP_CAPAB_ENROLLEE)) {
854			wpa_printf(MSG_DEBUG,
855				   "DPP: Local policy does not allow Enrollee role");
856			goto not_compatible;
857		}
858		wpa_printf(MSG_DEBUG, "DPP: Acting as Enrollee");
859		auth->configurator = 0;
860		break;
861	case DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE:
862		if (dpp_allowed_roles & DPP_CAPAB_ENROLLEE) {
863			wpa_printf(MSG_DEBUG, "DPP: Acting as Enrollee");
864			auth->configurator = 0;
865		} else if (dpp_allowed_roles & DPP_CAPAB_CONFIGURATOR) {
866			wpa_printf(MSG_DEBUG, "DPP: Acting as Configurator");
867			auth->configurator = 1;
868		} else {
869			wpa_printf(MSG_DEBUG,
870				   "DPP: Local policy does not allow Configurator/Enrollee role");
871			goto not_compatible;
872		}
873		break;
874	default:
875		wpa_printf(MSG_DEBUG, "DPP: Unexpected role in I-capabilities");
876		wpa_msg(auth->msg_ctx, MSG_INFO,
877			DPP_EVENT_FAIL "Invalid role in I-capabilities 0x%02x",
878			auth->i_capab & DPP_CAPAB_ROLE_MASK);
879		goto fail;
880	}
881
882	auth->peer_protocol_key = pi;
883	pi = NULL;
884	if (qr_mutual && !peer_bi && own_bi->type == DPP_BOOTSTRAP_QR_CODE) {
885		char hex[SHA256_MAC_LEN * 2 + 1];
886
887		wpa_printf(MSG_DEBUG,
888			   "DPP: Mutual authentication required with QR Codes, but peer info is not yet available - request more time");
889		if (dpp_auth_build_resp_status(auth,
890					       DPP_STATUS_RESPONSE_PENDING) < 0)
891			goto fail;
892		i_bootstrap = dpp_get_attr(attr_start, attr_len,
893					   DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
894					   &i_bootstrap_len);
895		if (i_bootstrap && i_bootstrap_len == SHA256_MAC_LEN) {
896			auth->response_pending = 1;
897			os_memcpy(auth->waiting_pubkey_hash,
898				  i_bootstrap, i_bootstrap_len);
899			wpa_snprintf_hex(hex, sizeof(hex), i_bootstrap,
900					 i_bootstrap_len);
901		} else {
902			hex[0] = '\0';
903		}
904
905		wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_SCAN_PEER_QR_CODE
906			"%s", hex);
907		return auth;
908	}
909	if (dpp_auth_build_resp_ok(auth) < 0)
910		goto fail;
911
912	return auth;
913
914not_compatible:
915	wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_NOT_COMPATIBLE
916		"i-capab=0x%02x", auth->i_capab);
917	if (dpp_allowed_roles & DPP_CAPAB_CONFIGURATOR)
918		auth->configurator = 1;
919	else
920		auth->configurator = 0;
921	auth->peer_protocol_key = pi;
922	pi = NULL;
923	if (dpp_auth_build_resp_status(auth, DPP_STATUS_NOT_COMPATIBLE) < 0)
924		goto fail;
925
926	auth->remove_on_tx_status = 1;
927	return auth;
928fail:
929	bin_clear_free(unwrapped, unwrapped_len);
930	crypto_ec_key_deinit(pi);
931	dpp_auth_deinit(auth);
932	return NULL;
933}
934
935
936int dpp_notify_new_qr_code(struct dpp_authentication *auth,
937			   struct dpp_bootstrap_info *peer_bi)
938{
939	if (!auth || !auth->response_pending ||
940	    os_memcmp(auth->waiting_pubkey_hash, peer_bi->pubkey_hash,
941		      SHA256_MAC_LEN) != 0)
942		return 0;
943
944	wpa_printf(MSG_DEBUG,
945		   "DPP: New scanned QR Code has matching public key that was needed to continue DPP Authentication exchange with "
946		   MACSTR, MAC2STR(auth->peer_mac_addr));
947	auth->peer_bi = peer_bi;
948
949	if (dpp_auth_build_resp_ok(auth) < 0)
950		return -1;
951
952	return 1;
953}
954
955
956static struct wpabuf * dpp_auth_build_conf(struct dpp_authentication *auth,
957					   enum dpp_status_error status)
958{
959	struct wpabuf *msg;
960	u8 i_auth[4 + DPP_MAX_HASH_LEN];
961	size_t i_auth_len;
962	u8 r_nonce[4 + DPP_MAX_NONCE_LEN];
963	size_t r_nonce_len;
964	const u8 *addr[2];
965	size_t len[2], attr_len;
966	u8 *wrapped_i_auth;
967	u8 *wrapped_r_nonce;
968	u8 *attr_start, *attr_end;
969	const u8 *r_pubkey_hash, *i_pubkey_hash;
970#ifdef CONFIG_TESTING_OPTIONS
971	u8 test_hash[SHA256_MAC_LEN];
972#endif /* CONFIG_TESTING_OPTIONS */
973
974	wpa_printf(MSG_DEBUG, "DPP: Build Authentication Confirmation");
975
976	i_auth_len = 4 + auth->curve->hash_len;
977	r_nonce_len = 4 + auth->curve->nonce_len;
978	/* Build DPP Authentication Confirmation frame attributes */
979	attr_len = 4 + 1 + 2 * (4 + SHA256_MAC_LEN) +
980		4 + i_auth_len + r_nonce_len + AES_BLOCK_SIZE;
981#ifdef CONFIG_TESTING_OPTIONS
982	if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_CONF)
983		attr_len += 5;
984#endif /* CONFIG_TESTING_OPTIONS */
985	msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_CONF, attr_len);
986	if (!msg)
987		goto fail;
988
989	attr_start = wpabuf_put(msg, 0);
990
991	r_pubkey_hash = auth->peer_bi->pubkey_hash;
992	if (auth->own_bi)
993		i_pubkey_hash = auth->own_bi->pubkey_hash;
994	else
995		i_pubkey_hash = NULL;
996
997#ifdef CONFIG_TESTING_OPTIONS
998	if (dpp_test == DPP_TEST_NO_STATUS_AUTH_CONF) {
999		wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
1000		goto skip_status;
1001	} else if (dpp_test == DPP_TEST_INVALID_STATUS_AUTH_CONF) {
1002		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status");
1003		status = 254;
1004	}
1005#endif /* CONFIG_TESTING_OPTIONS */
1006
1007	/* DPP Status */
1008	dpp_build_attr_status(msg, status);
1009
1010#ifdef CONFIG_TESTING_OPTIONS
1011skip_status:
1012	if (dpp_test == DPP_TEST_NO_R_BOOTSTRAP_KEY_HASH_AUTH_CONF) {
1013		wpa_printf(MSG_INFO, "DPP: TESTING - no R-Bootstrap Key Hash");
1014		r_pubkey_hash = NULL;
1015	} else if (dpp_test ==
1016		   DPP_TEST_INVALID_R_BOOTSTRAP_KEY_HASH_AUTH_CONF) {
1017		wpa_printf(MSG_INFO,
1018			   "DPP: TESTING - invalid R-Bootstrap Key Hash");
1019		os_memcpy(test_hash, r_pubkey_hash, SHA256_MAC_LEN);
1020		test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
1021		r_pubkey_hash = test_hash;
1022	} else if (dpp_test == DPP_TEST_NO_I_BOOTSTRAP_KEY_HASH_AUTH_CONF) {
1023		wpa_printf(MSG_INFO, "DPP: TESTING - no I-Bootstrap Key Hash");
1024		i_pubkey_hash = NULL;
1025	} else if (dpp_test ==
1026		   DPP_TEST_INVALID_I_BOOTSTRAP_KEY_HASH_AUTH_CONF) {
1027		wpa_printf(MSG_INFO,
1028			   "DPP: TESTING - invalid I-Bootstrap Key Hash");
1029		if (i_pubkey_hash)
1030			os_memcpy(test_hash, i_pubkey_hash, SHA256_MAC_LEN);
1031		else
1032			os_memset(test_hash, 0, SHA256_MAC_LEN);
1033		test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
1034		i_pubkey_hash = test_hash;
1035	}
1036#endif /* CONFIG_TESTING_OPTIONS */
1037
1038	/* Responder Bootstrapping Key Hash */
1039	dpp_build_attr_r_bootstrap_key_hash(msg, r_pubkey_hash);
1040
1041	/* Initiator Bootstrapping Key Hash (mutual authentication) */
1042	dpp_build_attr_i_bootstrap_key_hash(msg, i_pubkey_hash);
1043
1044#ifdef CONFIG_TESTING_OPTIONS
1045	if (dpp_test == DPP_TEST_NO_WRAPPED_DATA_AUTH_CONF)
1046		goto skip_wrapped_data;
1047	if (dpp_test == DPP_TEST_NO_I_AUTH_AUTH_CONF)
1048		i_auth_len = 0;
1049#endif /* CONFIG_TESTING_OPTIONS */
1050
1051	attr_end = wpabuf_put(msg, 0);
1052
1053	/* OUI, OUI type, Crypto Suite, DPP frame type */
1054	addr[0] = wpabuf_head_u8(msg) + 2;
1055	len[0] = 3 + 1 + 1 + 1;
1056	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
1057
1058	/* Attributes before Wrapped Data */
1059	addr[1] = attr_start;
1060	len[1] = attr_end - attr_start;
1061	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
1062
1063	if (status == DPP_STATUS_OK) {
1064		/* I-auth wrapped with ke */
1065		wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
1066		wpabuf_put_le16(msg, i_auth_len + AES_BLOCK_SIZE);
1067		wrapped_i_auth = wpabuf_put(msg, i_auth_len + AES_BLOCK_SIZE);
1068
1069#ifdef CONFIG_TESTING_OPTIONS
1070		if (dpp_test == DPP_TEST_NO_I_AUTH_AUTH_CONF)
1071			goto skip_i_auth;
1072#endif /* CONFIG_TESTING_OPTIONS */
1073
1074		/* I-auth = H(R-nonce | I-nonce | PR.x | PI.x | BR.x | [BI.x |]
1075		 *	      1) */
1076		WPA_PUT_LE16(i_auth, DPP_ATTR_I_AUTH_TAG);
1077		WPA_PUT_LE16(&i_auth[2], auth->curve->hash_len);
1078		if (dpp_gen_i_auth(auth, i_auth + 4) < 0)
1079			goto fail;
1080
1081#ifdef CONFIG_TESTING_OPTIONS
1082		if (dpp_test == DPP_TEST_I_AUTH_MISMATCH_AUTH_CONF) {
1083			wpa_printf(MSG_INFO, "DPP: TESTING - I-auth mismatch");
1084			i_auth[4 + auth->curve->hash_len / 2] ^= 0x01;
1085		}
1086skip_i_auth:
1087#endif /* CONFIG_TESTING_OPTIONS */
1088		if (aes_siv_encrypt(auth->ke, auth->curve->hash_len,
1089				    i_auth, i_auth_len,
1090				    2, addr, len, wrapped_i_auth) < 0)
1091			goto fail;
1092		wpa_hexdump(MSG_DEBUG, "DPP: {I-auth}ke",
1093			    wrapped_i_auth, i_auth_len + AES_BLOCK_SIZE);
1094	} else {
1095		/* R-nonce wrapped with k2 */
1096		wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
1097		wpabuf_put_le16(msg, r_nonce_len + AES_BLOCK_SIZE);
1098		wrapped_r_nonce = wpabuf_put(msg, r_nonce_len + AES_BLOCK_SIZE);
1099
1100		WPA_PUT_LE16(r_nonce, DPP_ATTR_R_NONCE);
1101		WPA_PUT_LE16(&r_nonce[2], auth->curve->nonce_len);
1102		os_memcpy(r_nonce + 4, auth->r_nonce, auth->curve->nonce_len);
1103
1104		if (aes_siv_encrypt(auth->k2, auth->curve->hash_len,
1105				    r_nonce, r_nonce_len,
1106				    2, addr, len, wrapped_r_nonce) < 0)
1107			goto fail;
1108		wpa_hexdump(MSG_DEBUG, "DPP: {R-nonce}k2",
1109			    wrapped_r_nonce, r_nonce_len + AES_BLOCK_SIZE);
1110	}
1111
1112#ifdef CONFIG_TESTING_OPTIONS
1113	if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_CONF) {
1114		wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
1115		dpp_build_attr_status(msg, DPP_STATUS_OK);
1116	}
1117skip_wrapped_data:
1118#endif /* CONFIG_TESTING_OPTIONS */
1119
1120	wpa_hexdump_buf(MSG_DEBUG,
1121			"DPP: Authentication Confirmation frame attributes",
1122			msg);
1123	if (status == DPP_STATUS_OK)
1124		dpp_auth_success(auth);
1125
1126	return msg;
1127
1128fail:
1129	wpabuf_free(msg);
1130	return NULL;
1131}
1132
1133
1134static int dpp_autogen_bootstrap_key(struct dpp_authentication *auth)
1135{
1136	struct dpp_bootstrap_info *bi;
1137
1138	if (auth->own_bi)
1139		return 0; /* already generated */
1140
1141	bi = os_zalloc(sizeof(*bi));
1142	if (!bi)
1143		return -1;
1144	bi->type = DPP_BOOTSTRAP_QR_CODE;
1145	if (dpp_keygen(bi, auth->peer_bi->curve->name, NULL, 0) < 0 ||
1146	    dpp_gen_uri(bi) < 0)
1147		goto fail;
1148	wpa_printf(MSG_DEBUG,
1149		   "DPP: Auto-generated own bootstrapping key info: URI %s",
1150		   bi->uri);
1151
1152	auth->tmp_own_bi = auth->own_bi = bi;
1153
1154	return 0;
1155fail:
1156	dpp_bootstrap_info_free(bi);
1157	return -1;
1158}
1159
1160
1161struct dpp_authentication * dpp_auth_init(struct dpp_global *dpp, void *msg_ctx,
1162					  struct dpp_bootstrap_info *peer_bi,
1163					  struct dpp_bootstrap_info *own_bi,
1164					  u8 dpp_allowed_roles,
1165					  unsigned int neg_freq,
1166					  struct hostapd_hw_modes *own_modes,
1167					  u16 num_modes)
1168{
1169	struct dpp_authentication *auth;
1170	size_t nonce_len;
1171	size_t secret_len;
1172	struct wpabuf *pi = NULL;
1173	const u8 *r_pubkey_hash, *i_pubkey_hash;
1174#ifdef CONFIG_TESTING_OPTIONS
1175	u8 test_hash[SHA256_MAC_LEN];
1176#endif /* CONFIG_TESTING_OPTIONS */
1177
1178	auth = dpp_alloc_auth(dpp, msg_ctx);
1179	if (!auth)
1180		return NULL;
1181	if (peer_bi->configurator_params &&
1182	    dpp_set_configurator(auth, peer_bi->configurator_params) < 0)
1183		goto fail;
1184	auth->initiator = 1;
1185	auth->waiting_auth_resp = 1;
1186	auth->allowed_roles = dpp_allowed_roles;
1187	auth->configurator = !!(dpp_allowed_roles & DPP_CAPAB_CONFIGURATOR);
1188	auth->peer_bi = peer_bi;
1189	auth->own_bi = own_bi;
1190	auth->curve = peer_bi->curve;
1191
1192	if (dpp_autogen_bootstrap_key(auth) < 0 ||
1193	    dpp_prepare_channel_list(auth, neg_freq, own_modes, num_modes) < 0)
1194		goto fail;
1195
1196#ifdef CONFIG_TESTING_OPTIONS
1197	if (dpp_nonce_override_len > 0) {
1198		wpa_printf(MSG_INFO, "DPP: TESTING - override I-nonce");
1199		nonce_len = dpp_nonce_override_len;
1200		os_memcpy(auth->i_nonce, dpp_nonce_override, nonce_len);
1201	} else {
1202		nonce_len = auth->curve->nonce_len;
1203		if (random_get_bytes(auth->i_nonce, nonce_len)) {
1204			wpa_printf(MSG_ERROR,
1205				   "DPP: Failed to generate I-nonce");
1206			goto fail;
1207		}
1208	}
1209#else /* CONFIG_TESTING_OPTIONS */
1210	nonce_len = auth->curve->nonce_len;
1211	if (random_get_bytes(auth->i_nonce, nonce_len)) {
1212		wpa_printf(MSG_ERROR, "DPP: Failed to generate I-nonce");
1213		goto fail;
1214	}
1215#endif /* CONFIG_TESTING_OPTIONS */
1216	wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", auth->i_nonce, nonce_len);
1217
1218#ifdef CONFIG_TESTING_OPTIONS
1219	if (dpp_protocol_key_override_len) {
1220		const struct dpp_curve_params *tmp_curve;
1221
1222		wpa_printf(MSG_INFO,
1223			   "DPP: TESTING - override protocol key");
1224		auth->own_protocol_key = dpp_set_keypair(
1225			&tmp_curve, dpp_protocol_key_override,
1226			dpp_protocol_key_override_len);
1227	} else {
1228		auth->own_protocol_key = dpp_gen_keypair(auth->curve);
1229	}
1230#else /* CONFIG_TESTING_OPTIONS */
1231	auth->own_protocol_key = dpp_gen_keypair(auth->curve);
1232#endif /* CONFIG_TESTING_OPTIONS */
1233	if (!auth->own_protocol_key)
1234		goto fail;
1235
1236	pi = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0);
1237	if (!pi)
1238		goto fail;
1239
1240	/* ECDH: M = pI * BR */
1241	if (dpp_ecdh(auth->own_protocol_key, auth->peer_bi->pubkey,
1242		     auth->Mx, &secret_len) < 0)
1243		goto fail;
1244	auth->secret_len = secret_len;
1245
1246	wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (M.x)",
1247			auth->Mx, auth->secret_len);
1248	auth->Mx_len = auth->secret_len;
1249
1250	if (dpp_derive_k1(auth->Mx, auth->secret_len, auth->k1,
1251			  auth->curve->hash_len) < 0)
1252		goto fail;
1253
1254	r_pubkey_hash = auth->peer_bi->pubkey_hash;
1255	i_pubkey_hash = auth->own_bi->pubkey_hash;
1256
1257#ifdef CONFIG_TESTING_OPTIONS
1258	if (dpp_test == DPP_TEST_NO_R_BOOTSTRAP_KEY_HASH_AUTH_REQ) {
1259		wpa_printf(MSG_INFO, "DPP: TESTING - no R-Bootstrap Key Hash");
1260		r_pubkey_hash = NULL;
1261	} else if (dpp_test == DPP_TEST_INVALID_R_BOOTSTRAP_KEY_HASH_AUTH_REQ) {
1262		wpa_printf(MSG_INFO,
1263			   "DPP: TESTING - invalid R-Bootstrap Key Hash");
1264		os_memcpy(test_hash, r_pubkey_hash, SHA256_MAC_LEN);
1265		test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
1266		r_pubkey_hash = test_hash;
1267	} else if (dpp_test == DPP_TEST_NO_I_BOOTSTRAP_KEY_HASH_AUTH_REQ) {
1268		wpa_printf(MSG_INFO, "DPP: TESTING - no I-Bootstrap Key Hash");
1269		i_pubkey_hash = NULL;
1270	} else if (dpp_test == DPP_TEST_INVALID_I_BOOTSTRAP_KEY_HASH_AUTH_REQ) {
1271		wpa_printf(MSG_INFO,
1272			   "DPP: TESTING - invalid I-Bootstrap Key Hash");
1273		os_memcpy(test_hash, i_pubkey_hash, SHA256_MAC_LEN);
1274		test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
1275		i_pubkey_hash = test_hash;
1276	} else if (dpp_test == DPP_TEST_NO_I_PROTO_KEY_AUTH_REQ) {
1277		wpa_printf(MSG_INFO, "DPP: TESTING - no I-Proto Key");
1278		wpabuf_free(pi);
1279		pi = NULL;
1280	} else if (dpp_test == DPP_TEST_INVALID_I_PROTO_KEY_AUTH_REQ) {
1281		wpa_printf(MSG_INFO, "DPP: TESTING - invalid I-Proto Key");
1282		wpabuf_free(pi);
1283		pi = wpabuf_alloc(2 * auth->curve->prime_len);
1284		if (!pi || dpp_test_gen_invalid_key(pi, auth->curve) < 0)
1285			goto fail;
1286	}
1287#endif /* CONFIG_TESTING_OPTIONS */
1288
1289	if (neg_freq && auth->num_freq == 1 && auth->freq[0] == neg_freq)
1290		neg_freq = 0;
1291	auth->req_msg = dpp_auth_build_req(auth, pi, nonce_len, r_pubkey_hash,
1292					   i_pubkey_hash, neg_freq);
1293	if (!auth->req_msg)
1294		goto fail;
1295
1296out:
1297	wpabuf_free(pi);
1298	return auth;
1299fail:
1300	dpp_auth_deinit(auth);
1301	auth = NULL;
1302	goto out;
1303}
1304static void
1305dpp_auth_resp_rx_status(struct dpp_authentication *auth, const u8 *hdr,
1306			const u8 *attr_start, size_t attr_len,
1307			const u8 *wrapped_data, u16 wrapped_data_len,
1308			enum dpp_status_error status)
1309{
1310	const u8 *addr[2];
1311	size_t len[2];
1312	u8 *unwrapped = NULL;
1313	size_t unwrapped_len = 0;
1314	const u8 *i_nonce, *r_capab;
1315	u16 i_nonce_len, r_capab_len;
1316
1317	if (status == DPP_STATUS_NOT_COMPATIBLE) {
1318		wpa_printf(MSG_DEBUG,
1319			   "DPP: Responder reported incompatible roles");
1320	} else if (status == DPP_STATUS_RESPONSE_PENDING) {
1321		wpa_printf(MSG_DEBUG,
1322			   "DPP: Responder reported more time needed");
1323	} else {
1324		wpa_printf(MSG_DEBUG,
1325			   "DPP: Responder reported failure (status %d)",
1326			   status);
1327		dpp_auth_fail(auth, "Responder reported failure");
1328		return;
1329	}
1330
1331	addr[0] = hdr;
1332	len[0] = DPP_HDR_LEN;
1333	addr[1] = attr_start;
1334	len[1] = attr_len;
1335	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
1336	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
1337	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
1338		    wrapped_data, wrapped_data_len);
1339	unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
1340	unwrapped = os_malloc(unwrapped_len);
1341	if (!unwrapped)
1342		goto fail;
1343	if (aes_siv_decrypt(auth->k1, auth->curve->hash_len,
1344			    wrapped_data, wrapped_data_len,
1345			    2, addr, len, unwrapped) < 0) {
1346		dpp_auth_fail(auth, "AES-SIV decryption failed");
1347		goto fail;
1348	}
1349	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
1350		    unwrapped, unwrapped_len);
1351
1352	if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
1353		dpp_auth_fail(auth, "Invalid attribute in unwrapped data");
1354		goto fail;
1355	}
1356
1357	i_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_NONCE,
1358			       &i_nonce_len);
1359	if (!i_nonce || i_nonce_len != auth->curve->nonce_len) {
1360		dpp_auth_fail(auth, "Missing or invalid I-nonce");
1361		goto fail;
1362	}
1363	wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", i_nonce, i_nonce_len);
1364	if (os_memcmp(auth->i_nonce, i_nonce, i_nonce_len) != 0) {
1365		dpp_auth_fail(auth, "I-nonce mismatch");
1366		goto fail;
1367	}
1368
1369	r_capab = dpp_get_attr(unwrapped, unwrapped_len,
1370			       DPP_ATTR_R_CAPABILITIES,
1371			       &r_capab_len);
1372	if (!r_capab || r_capab_len < 1) {
1373		dpp_auth_fail(auth, "Missing or invalid R-capabilities");
1374		goto fail;
1375	}
1376	auth->r_capab = r_capab[0];
1377	wpa_printf(MSG_DEBUG, "DPP: R-capabilities: 0x%02x", auth->r_capab);
1378	if (status == DPP_STATUS_NOT_COMPATIBLE) {
1379		wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_NOT_COMPATIBLE
1380			"r-capab=0x%02x", auth->r_capab);
1381	} else if (status == DPP_STATUS_RESPONSE_PENDING) {
1382		u8 role = auth->r_capab & DPP_CAPAB_ROLE_MASK;
1383
1384		if ((auth->configurator && role != DPP_CAPAB_ENROLLEE) ||
1385		    (!auth->configurator && role != DPP_CAPAB_CONFIGURATOR)) {
1386			wpa_msg(auth->msg_ctx, MSG_INFO,
1387				DPP_EVENT_FAIL "Unexpected role in R-capabilities 0x%02x",
1388				role);
1389		} else {
1390			wpa_printf(MSG_DEBUG,
1391				   "DPP: Continue waiting for full DPP Authentication Response");
1392			wpa_msg(auth->msg_ctx, MSG_INFO,
1393				DPP_EVENT_RESPONSE_PENDING "%s",
1394				auth->tmp_own_bi ? auth->tmp_own_bi->uri : "");
1395		}
1396	}
1397fail:
1398	bin_clear_free(unwrapped, unwrapped_len);
1399}
1400
1401
1402struct wpabuf *
1403dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr,
1404		 const u8 *attr_start, size_t attr_len)
1405{
1406	struct crypto_ec_key *pr;
1407	size_t secret_len;
1408	const u8 *addr[2];
1409	size_t len[2];
1410	u8 *unwrapped = NULL, *unwrapped2 = NULL;
1411	size_t unwrapped_len = 0, unwrapped2_len = 0;
1412	const u8 *r_bootstrap, *i_bootstrap, *wrapped_data, *status, *r_proto,
1413		*r_nonce, *i_nonce, *r_capab, *wrapped2, *r_auth;
1414	u16 r_bootstrap_len, i_bootstrap_len, wrapped_data_len, status_len,
1415		r_proto_len, r_nonce_len, i_nonce_len, r_capab_len,
1416		wrapped2_len, r_auth_len;
1417	u8 r_auth2[DPP_MAX_HASH_LEN];
1418	u8 role;
1419#ifdef CONFIG_DPP2
1420	const u8 *version;
1421	u16 version_len;
1422#endif /* CONFIG_DPP2 */
1423
1424#ifdef CONFIG_TESTING_OPTIONS
1425	if (dpp_test == DPP_TEST_STOP_AT_AUTH_RESP) {
1426		wpa_printf(MSG_INFO,
1427			   "DPP: TESTING - stop at Authentication Response");
1428		return NULL;
1429	}
1430#endif /* CONFIG_TESTING_OPTIONS */
1431
1432	if (!auth->initiator || !auth->peer_bi || auth->reconfig) {
1433		dpp_auth_fail(auth, "Unexpected Authentication Response");
1434		return NULL;
1435	}
1436
1437	auth->waiting_auth_resp = 0;
1438
1439	wrapped_data = dpp_get_attr(attr_start, attr_len, DPP_ATTR_WRAPPED_DATA,
1440				    &wrapped_data_len);
1441	if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) {
1442		dpp_auth_fail(auth,
1443			      "Missing or invalid required Wrapped Data attribute");
1444		return NULL;
1445	}
1446	wpa_hexdump(MSG_DEBUG, "DPP: Wrapped data",
1447		    wrapped_data, wrapped_data_len);
1448
1449	attr_len = wrapped_data - 4 - attr_start;
1450
1451	r_bootstrap = dpp_get_attr(attr_start, attr_len,
1452				   DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
1453				   &r_bootstrap_len);
1454	if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
1455		dpp_auth_fail(auth,
1456			      "Missing or invalid required Responder Bootstrapping Key Hash attribute");
1457		return NULL;
1458	}
1459	wpa_hexdump(MSG_DEBUG, "DPP: Responder Bootstrapping Key Hash",
1460		    r_bootstrap, r_bootstrap_len);
1461	if (os_memcmp(r_bootstrap, auth->peer_bi->pubkey_hash,
1462		      SHA256_MAC_LEN) != 0) {
1463		dpp_auth_fail(auth,
1464			      "Unexpected Responder Bootstrapping Key Hash value");
1465		wpa_hexdump(MSG_DEBUG,
1466			    "DPP: Expected Responder Bootstrapping Key Hash",
1467			    auth->peer_bi->pubkey_hash, SHA256_MAC_LEN);
1468		return NULL;
1469	}
1470
1471	i_bootstrap = dpp_get_attr(attr_start, attr_len,
1472				   DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
1473				   &i_bootstrap_len);
1474	if (i_bootstrap) {
1475		if (i_bootstrap_len != SHA256_MAC_LEN) {
1476			dpp_auth_fail(auth,
1477				      "Invalid Initiator Bootstrapping Key Hash attribute");
1478			return NULL;
1479		}
1480		wpa_hexdump(MSG_MSGDUMP,
1481			    "DPP: Initiator Bootstrapping Key Hash",
1482			    i_bootstrap, i_bootstrap_len);
1483		if (!auth->own_bi ||
1484		    os_memcmp(i_bootstrap, auth->own_bi->pubkey_hash,
1485			      SHA256_MAC_LEN) != 0) {
1486			dpp_auth_fail(auth,
1487				      "Initiator Bootstrapping Key Hash attribute did not match");
1488			return NULL;
1489		}
1490	} else if (auth->own_bi && auth->own_bi->type == DPP_BOOTSTRAP_PKEX) {
1491		/* PKEX bootstrapping mandates use of mutual authentication */
1492		dpp_auth_fail(auth,
1493			      "Missing Initiator Bootstrapping Key Hash attribute");
1494		return NULL;
1495	} else if (auth->own_bi &&
1496		   auth->own_bi->type == DPP_BOOTSTRAP_NFC_URI &&
1497		   auth->own_bi->nfc_negotiated) {
1498		/* NFC negotiated connection handover bootstrapping mandates
1499		 * use of mutual authentication */
1500		dpp_auth_fail(auth,
1501			      "Missing Initiator Bootstrapping Key Hash attribute");
1502		return NULL;
1503	}
1504
1505	auth->peer_version = 1; /* default to the first version */
1506#ifdef CONFIG_DPP2
1507	version = dpp_get_attr(attr_start, attr_len, DPP_ATTR_PROTOCOL_VERSION,
1508			       &version_len);
1509	if (version && DPP_VERSION > 1) {
1510		if (version_len < 1 || version[0] == 0) {
1511			dpp_auth_fail(auth,
1512				      "Invalid Protocol Version attribute");
1513			return NULL;
1514		}
1515		auth->peer_version = version[0];
1516		wpa_printf(MSG_DEBUG, "DPP: Peer protocol version %u",
1517			   auth->peer_version);
1518	}
1519#endif /* CONFIG_DPP2 */
1520
1521	status = dpp_get_attr(attr_start, attr_len, DPP_ATTR_STATUS,
1522			      &status_len);
1523	if (!status || status_len < 1) {
1524		dpp_auth_fail(auth,
1525			      "Missing or invalid required DPP Status attribute");
1526		return NULL;
1527	}
1528	wpa_printf(MSG_DEBUG, "DPP: Status %u", status[0]);
1529	auth->auth_resp_status = status[0];
1530	if (status[0] != DPP_STATUS_OK) {
1531		dpp_auth_resp_rx_status(auth, hdr, attr_start,
1532					attr_len, wrapped_data,
1533					wrapped_data_len, status[0]);
1534		return NULL;
1535	}
1536
1537	if (!i_bootstrap && auth->own_bi) {
1538		wpa_printf(MSG_DEBUG,
1539			   "DPP: Responder decided not to use mutual authentication");
1540		auth->own_bi = NULL;
1541	}
1542
1543	wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_DIRECTION "mutual=%d",
1544		auth->own_bi != NULL);
1545
1546	r_proto = dpp_get_attr(attr_start, attr_len, DPP_ATTR_R_PROTOCOL_KEY,
1547			       &r_proto_len);
1548	if (!r_proto) {
1549		dpp_auth_fail(auth,
1550			      "Missing required Responder Protocol Key attribute");
1551		return NULL;
1552	}
1553	wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Protocol Key",
1554		    r_proto, r_proto_len);
1555
1556	/* N = pI * PR */
1557	pr = dpp_set_pubkey_point(auth->own_protocol_key, r_proto, r_proto_len);
1558	if (!pr) {
1559		dpp_auth_fail(auth, "Invalid Responder Protocol Key");
1560		return NULL;
1561	}
1562	dpp_debug_print_key("Peer (Responder) Protocol Key", pr);
1563
1564	if (dpp_ecdh(auth->own_protocol_key, pr, auth->Nx, &secret_len) < 0) {
1565		dpp_auth_fail(auth, "Failed to derive ECDH shared secret");
1566		goto fail;
1567	}
1568	crypto_ec_key_deinit(auth->peer_protocol_key);
1569	auth->peer_protocol_key = pr;
1570	pr = NULL;
1571
1572	wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (N.x)",
1573			auth->Nx, auth->secret_len);
1574	auth->Nx_len = auth->secret_len;
1575
1576	if (dpp_derive_k2(auth->Nx, auth->secret_len, auth->k2,
1577			  auth->curve->hash_len) < 0)
1578		goto fail;
1579
1580	addr[0] = hdr;
1581	len[0] = DPP_HDR_LEN;
1582	addr[1] = attr_start;
1583	len[1] = attr_len;
1584	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
1585	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
1586	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
1587		    wrapped_data, wrapped_data_len);
1588	unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
1589	unwrapped = os_malloc(unwrapped_len);
1590	if (!unwrapped)
1591		goto fail;
1592	if (aes_siv_decrypt(auth->k2, auth->curve->hash_len,
1593			    wrapped_data, wrapped_data_len,
1594			    2, addr, len, unwrapped) < 0) {
1595		dpp_auth_fail(auth, "AES-SIV decryption failed");
1596		goto fail;
1597	}
1598	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
1599		    unwrapped, unwrapped_len);
1600
1601	if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
1602		dpp_auth_fail(auth, "Invalid attribute in unwrapped data");
1603		goto fail;
1604	}
1605
1606	r_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_R_NONCE,
1607			       &r_nonce_len);
1608	if (!r_nonce || r_nonce_len != auth->curve->nonce_len) {
1609		dpp_auth_fail(auth, "DPP: Missing or invalid R-nonce");
1610		goto fail;
1611	}
1612	wpa_hexdump(MSG_DEBUG, "DPP: R-nonce", r_nonce, r_nonce_len);
1613	os_memcpy(auth->r_nonce, r_nonce, r_nonce_len);
1614
1615	i_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_NONCE,
1616			       &i_nonce_len);
1617	if (!i_nonce || i_nonce_len != auth->curve->nonce_len) {
1618		dpp_auth_fail(auth, "Missing or invalid I-nonce");
1619		goto fail;
1620	}
1621	wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", i_nonce, i_nonce_len);
1622	if (os_memcmp(auth->i_nonce, i_nonce, i_nonce_len) != 0) {
1623		dpp_auth_fail(auth, "I-nonce mismatch");
1624		goto fail;
1625	}
1626
1627	if (auth->own_bi) {
1628		/* Mutual authentication */
1629		if (dpp_auth_derive_l_initiator(auth) < 0)
1630			goto fail;
1631	}
1632
1633	r_capab = dpp_get_attr(unwrapped, unwrapped_len,
1634			       DPP_ATTR_R_CAPABILITIES,
1635			       &r_capab_len);
1636	if (!r_capab || r_capab_len < 1) {
1637		dpp_auth_fail(auth, "Missing or invalid R-capabilities");
1638		goto fail;
1639	}
1640	auth->r_capab = r_capab[0];
1641	wpa_printf(MSG_DEBUG, "DPP: R-capabilities: 0x%02x", auth->r_capab);
1642	role = auth->r_capab & DPP_CAPAB_ROLE_MASK;
1643	if ((auth->allowed_roles ==
1644	     (DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE)) &&
1645	    (role == DPP_CAPAB_CONFIGURATOR || role == DPP_CAPAB_ENROLLEE)) {
1646		/* Peer selected its role, so move from "either role" to the
1647		 * role that is compatible with peer's selection. */
1648		auth->configurator = role == DPP_CAPAB_ENROLLEE;
1649		wpa_printf(MSG_DEBUG, "DPP: Acting as %s",
1650			   auth->configurator ? "Configurator" : "Enrollee");
1651	} else if ((auth->configurator && role != DPP_CAPAB_ENROLLEE) ||
1652		   (!auth->configurator && role != DPP_CAPAB_CONFIGURATOR)) {
1653		wpa_printf(MSG_DEBUG, "DPP: Incompatible role selection");
1654		wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1655			"Unexpected role in R-capabilities 0x%02x",
1656			role);
1657		if (role != DPP_CAPAB_ENROLLEE &&
1658		    role != DPP_CAPAB_CONFIGURATOR)
1659			goto fail;
1660		bin_clear_free(unwrapped, unwrapped_len);
1661		auth->remove_on_tx_status = 1;
1662		return dpp_auth_build_conf(auth, DPP_STATUS_NOT_COMPATIBLE);
1663	}
1664
1665	wrapped2 = dpp_get_attr(unwrapped, unwrapped_len,
1666				DPP_ATTR_WRAPPED_DATA, &wrapped2_len);
1667	if (!wrapped2 || wrapped2_len < AES_BLOCK_SIZE) {
1668		dpp_auth_fail(auth,
1669			      "Missing or invalid Secondary Wrapped Data");
1670		goto fail;
1671	}
1672
1673	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
1674		    wrapped2, wrapped2_len);
1675
1676	if (dpp_derive_bk_ke(auth) < 0)
1677		goto fail;
1678
1679	unwrapped2_len = wrapped2_len - AES_BLOCK_SIZE;
1680	unwrapped2 = os_malloc(unwrapped2_len);
1681	if (!unwrapped2)
1682		goto fail;
1683	if (aes_siv_decrypt(auth->ke, auth->curve->hash_len,
1684			    wrapped2, wrapped2_len,
1685			    0, NULL, NULL, unwrapped2) < 0) {
1686		dpp_auth_fail(auth, "AES-SIV decryption failed");
1687		goto fail;
1688	}
1689	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
1690		    unwrapped2, unwrapped2_len);
1691
1692	if (dpp_check_attrs(unwrapped2, unwrapped2_len) < 0) {
1693		dpp_auth_fail(auth,
1694			      "Invalid attribute in secondary unwrapped data");
1695		goto fail;
1696	}
1697
1698	r_auth = dpp_get_attr(unwrapped2, unwrapped2_len, DPP_ATTR_R_AUTH_TAG,
1699			       &r_auth_len);
1700	if (!r_auth || r_auth_len != auth->curve->hash_len) {
1701		dpp_auth_fail(auth,
1702			      "Missing or invalid Responder Authenticating Tag");
1703		goto fail;
1704	}
1705	wpa_hexdump(MSG_DEBUG, "DPP: Received Responder Authenticating Tag",
1706		    r_auth, r_auth_len);
1707	/* R-auth' = H(I-nonce | R-nonce | PI.x | PR.x | [BI.x |] BR.x | 0) */
1708	if (dpp_gen_r_auth(auth, r_auth2) < 0)
1709		goto fail;
1710	wpa_hexdump(MSG_DEBUG, "DPP: Calculated Responder Authenticating Tag",
1711		    r_auth2, r_auth_len);
1712	if (os_memcmp(r_auth, r_auth2, r_auth_len) != 0) {
1713		dpp_auth_fail(auth, "Mismatching Responder Authenticating Tag");
1714		bin_clear_free(unwrapped, unwrapped_len);
1715		bin_clear_free(unwrapped2, unwrapped2_len);
1716		auth->remove_on_tx_status = 1;
1717		return dpp_auth_build_conf(auth, DPP_STATUS_AUTH_FAILURE);
1718	}
1719
1720	bin_clear_free(unwrapped, unwrapped_len);
1721	bin_clear_free(unwrapped2, unwrapped2_len);
1722
1723#ifdef CONFIG_TESTING_OPTIONS
1724	if (dpp_test == DPP_TEST_AUTH_RESP_IN_PLACE_OF_CONF) {
1725		wpa_printf(MSG_INFO,
1726			   "DPP: TESTING - Authentication Response in place of Confirm");
1727		if (dpp_auth_build_resp_ok(auth) < 0)
1728			return NULL;
1729		return wpabuf_dup(auth->resp_msg);
1730	}
1731#endif /* CONFIG_TESTING_OPTIONS */
1732
1733	return dpp_auth_build_conf(auth, DPP_STATUS_OK);
1734
1735fail:
1736	bin_clear_free(unwrapped, unwrapped_len);
1737	bin_clear_free(unwrapped2, unwrapped2_len);
1738	crypto_ec_key_deinit(pr);
1739	return NULL;
1740}
1741
1742
1743static int dpp_auth_conf_rx_failure(struct dpp_authentication *auth,
1744				    const u8 *hdr,
1745				    const u8 *attr_start, size_t attr_len,
1746				    const u8 *wrapped_data,
1747				    u16 wrapped_data_len,
1748				    enum dpp_status_error status)
1749{
1750	const u8 *addr[2];
1751	size_t len[2];
1752	u8 *unwrapped = NULL;
1753	size_t unwrapped_len = 0;
1754	const u8 *r_nonce;
1755	u16 r_nonce_len;
1756
1757	/* Authentication Confirm failure cases are expected to include
1758	 * {R-nonce}k2 in the Wrapped Data attribute. */
1759
1760	addr[0] = hdr;
1761	len[0] = DPP_HDR_LEN;
1762	addr[1] = attr_start;
1763	len[1] = attr_len;
1764	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
1765	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
1766	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
1767		    wrapped_data, wrapped_data_len);
1768	unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
1769	unwrapped = os_malloc(unwrapped_len);
1770	if (!unwrapped) {
1771		dpp_auth_fail(auth, "Authentication failed");
1772		goto fail;
1773	}
1774	if (aes_siv_decrypt(auth->k2, auth->curve->hash_len,
1775			    wrapped_data, wrapped_data_len,
1776			    2, addr, len, unwrapped) < 0) {
1777		dpp_auth_fail(auth, "AES-SIV decryption failed");
1778		goto fail;
1779	}
1780	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
1781		    unwrapped, unwrapped_len);
1782
1783	if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
1784		dpp_auth_fail(auth, "Invalid attribute in unwrapped data");
1785		goto fail;
1786	}
1787
1788	r_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_R_NONCE,
1789			       &r_nonce_len);
1790	if (!r_nonce || r_nonce_len != auth->curve->nonce_len) {
1791		dpp_auth_fail(auth, "DPP: Missing or invalid R-nonce");
1792		goto fail;
1793	}
1794	if (os_memcmp(r_nonce, auth->r_nonce, r_nonce_len) != 0) {
1795		wpa_hexdump(MSG_DEBUG, "DPP: Received R-nonce",
1796			    r_nonce, r_nonce_len);
1797		wpa_hexdump(MSG_DEBUG, "DPP: Expected R-nonce",
1798			    auth->r_nonce, r_nonce_len);
1799		dpp_auth_fail(auth, "R-nonce mismatch");
1800		goto fail;
1801	}
1802
1803	if (status == DPP_STATUS_NOT_COMPATIBLE)
1804		dpp_auth_fail(auth, "Peer reported incompatible R-capab role");
1805	else if (status == DPP_STATUS_AUTH_FAILURE)
1806		dpp_auth_fail(auth, "Peer reported authentication failure)");
1807
1808fail:
1809	bin_clear_free(unwrapped, unwrapped_len);
1810	return -1;
1811}
1812
1813
1814int dpp_auth_conf_rx(struct dpp_authentication *auth, const u8 *hdr,
1815		     const u8 *attr_start, size_t attr_len)
1816{
1817	const u8 *r_bootstrap, *i_bootstrap, *wrapped_data, *status, *i_auth;
1818	u16 r_bootstrap_len, i_bootstrap_len, wrapped_data_len, status_len,
1819		i_auth_len;
1820	const u8 *addr[2];
1821	size_t len[2];
1822	u8 *unwrapped = NULL;
1823	size_t unwrapped_len = 0;
1824	u8 i_auth2[DPP_MAX_HASH_LEN];
1825
1826#ifdef CONFIG_TESTING_OPTIONS
1827	if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) {
1828		wpa_printf(MSG_INFO,
1829			   "DPP: TESTING - stop at Authentication Confirm");
1830		return -1;
1831	}
1832#endif /* CONFIG_TESTING_OPTIONS */
1833
1834	if (auth->initiator || !auth->own_bi || !auth->waiting_auth_conf ||
1835	    auth->reconfig) {
1836		wpa_printf(MSG_DEBUG,
1837			   "DPP: initiator=%d own_bi=%d waiting_auth_conf=%d",
1838			   auth->initiator, !!auth->own_bi,
1839			   auth->waiting_auth_conf);
1840		dpp_auth_fail(auth, "Unexpected Authentication Confirm");
1841		return -1;
1842	}
1843
1844	auth->waiting_auth_conf = 0;
1845
1846	wrapped_data = dpp_get_attr(attr_start, attr_len, DPP_ATTR_WRAPPED_DATA,
1847				    &wrapped_data_len);
1848	if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) {
1849		dpp_auth_fail(auth,
1850			      "Missing or invalid required Wrapped Data attribute");
1851		return -1;
1852	}
1853	wpa_hexdump(MSG_DEBUG, "DPP: Wrapped data",
1854		    wrapped_data, wrapped_data_len);
1855
1856	attr_len = wrapped_data - 4 - attr_start;
1857
1858	r_bootstrap = dpp_get_attr(attr_start, attr_len,
1859				   DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
1860				   &r_bootstrap_len);
1861	if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
1862		dpp_auth_fail(auth,
1863			      "Missing or invalid required Responder Bootstrapping Key Hash attribute");
1864		return -1;
1865	}
1866	wpa_hexdump(MSG_DEBUG, "DPP: Responder Bootstrapping Key Hash",
1867		    r_bootstrap, r_bootstrap_len);
1868	if (os_memcmp(r_bootstrap, auth->own_bi->pubkey_hash,
1869		      SHA256_MAC_LEN) != 0) {
1870		wpa_hexdump(MSG_DEBUG,
1871			    "DPP: Expected Responder Bootstrapping Key Hash",
1872			    auth->peer_bi->pubkey_hash, SHA256_MAC_LEN);
1873		dpp_auth_fail(auth,
1874			      "Responder Bootstrapping Key Hash mismatch");
1875		return -1;
1876	}
1877
1878	i_bootstrap = dpp_get_attr(attr_start, attr_len,
1879				   DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
1880				   &i_bootstrap_len);
1881	if (i_bootstrap) {
1882		if (i_bootstrap_len != SHA256_MAC_LEN) {
1883			dpp_auth_fail(auth,
1884				      "Invalid Initiator Bootstrapping Key Hash attribute");
1885			return -1;
1886		}
1887		wpa_hexdump(MSG_MSGDUMP,
1888			    "DPP: Initiator Bootstrapping Key Hash",
1889			    i_bootstrap, i_bootstrap_len);
1890		if (!auth->peer_bi ||
1891		    os_memcmp(i_bootstrap, auth->peer_bi->pubkey_hash,
1892			      SHA256_MAC_LEN) != 0) {
1893			dpp_auth_fail(auth,
1894				      "Initiator Bootstrapping Key Hash mismatch");
1895			return -1;
1896		}
1897	} else if (auth->peer_bi) {
1898		/* Mutual authentication and peer did not include its
1899		 * Bootstrapping Key Hash attribute. */
1900		dpp_auth_fail(auth,
1901			      "Missing Initiator Bootstrapping Key Hash attribute");
1902		return -1;
1903	}
1904
1905	status = dpp_get_attr(attr_start, attr_len, DPP_ATTR_STATUS,
1906			      &status_len);
1907	if (!status || status_len < 1) {
1908		dpp_auth_fail(auth,
1909			      "Missing or invalid required DPP Status attribute");
1910		return -1;
1911	}
1912	wpa_printf(MSG_DEBUG, "DPP: Status %u", status[0]);
1913	if (status[0] == DPP_STATUS_NOT_COMPATIBLE ||
1914	    status[0] == DPP_STATUS_AUTH_FAILURE)
1915		return dpp_auth_conf_rx_failure(auth, hdr, attr_start,
1916						attr_len, wrapped_data,
1917						wrapped_data_len, status[0]);
1918
1919	if (status[0] != DPP_STATUS_OK) {
1920		dpp_auth_fail(auth, "Authentication failed");
1921		return -1;
1922	}
1923
1924	addr[0] = hdr;
1925	len[0] = DPP_HDR_LEN;
1926	addr[1] = attr_start;
1927	len[1] = attr_len;
1928	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
1929	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
1930	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
1931		    wrapped_data, wrapped_data_len);
1932	unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
1933	unwrapped = os_malloc(unwrapped_len);
1934	if (!unwrapped)
1935		return -1;
1936	if (aes_siv_decrypt(auth->ke, auth->curve->hash_len,
1937			    wrapped_data, wrapped_data_len,
1938			    2, addr, len, unwrapped) < 0) {
1939		dpp_auth_fail(auth, "AES-SIV decryption failed");
1940		goto fail;
1941	}
1942	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
1943		    unwrapped, unwrapped_len);
1944
1945	if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
1946		dpp_auth_fail(auth, "Invalid attribute in unwrapped data");
1947		goto fail;
1948	}
1949
1950	i_auth = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_AUTH_TAG,
1951			      &i_auth_len);
1952	if (!i_auth || i_auth_len != auth->curve->hash_len) {
1953		dpp_auth_fail(auth,
1954			      "Missing or invalid Initiator Authenticating Tag");
1955		goto fail;
1956	}
1957	wpa_hexdump(MSG_DEBUG, "DPP: Received Initiator Authenticating Tag",
1958		    i_auth, i_auth_len);
1959	/* I-auth' = H(R-nonce | I-nonce | PR.x | PI.x | BR.x | [BI.x |] 1) */
1960	if (dpp_gen_i_auth(auth, i_auth2) < 0)
1961		goto fail;
1962	wpa_hexdump(MSG_DEBUG, "DPP: Calculated Initiator Authenticating Tag",
1963		    i_auth2, i_auth_len);
1964	if (os_memcmp(i_auth, i_auth2, i_auth_len) != 0) {
1965		dpp_auth_fail(auth, "Mismatching Initiator Authenticating Tag");
1966		goto fail;
1967	}
1968
1969	bin_clear_free(unwrapped, unwrapped_len);
1970	dpp_auth_success(auth);
1971	return 0;
1972fail:
1973	bin_clear_free(unwrapped, unwrapped_len);
1974	return -1;
1975}
1976