• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
23 u8 dpp_protocol_key_override[600];
24 size_t dpp_protocol_key_override_len = 0;
25 u8 dpp_nonce_override[DPP_MAX_NONCE_LEN];
26 size_t dpp_nonce_override_len = 0;
27 #endif /* CONFIG_TESTING_OPTIONS */
28 
29 
dpp_build_attr_i_bootstrap_key_hash(struct wpabuf * msg,const u8 * hash)30 static 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 
dpp_auth_success(struct dpp_authentication * auth)42 static 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 
dpp_auth_build_req(struct dpp_authentication * auth,const struct wpabuf * pi,size_t nonce_len,const u8 * r_pubkey_hash,const u8 * i_pubkey_hash,unsigned int neg_freq)59 static 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
169 skip_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 	}
188 skip_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 	}
223 skip_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 
dpp_auth_build_resp(struct dpp_authentication * auth,enum dpp_status_error status,const struct wpabuf * pr,size_t nonce_len,const u8 * r_pubkey_hash,const u8 * i_pubkey_hash,const u8 * r_nonce,const u8 * i_nonce,const u8 * wrapped_r_auth,size_t wrapped_r_auth_len,const u8 * siv_key)233 static 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 	}
366 skip_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 	}
409 skip_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 
dpp_auth_build_resp_ok(struct dpp_authentication * auth)418 static 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 	EVP_PKEY_free(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 = dpp_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;
596 fail:
597 	wpabuf_free(pr);
598 	return ret;
599 }
600 
601 
dpp_auth_build_resp_status(struct dpp_authentication * auth,enum dpp_status_error status)602 static 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 
667 struct dpp_authentication *
dpp_auth_req_rx(struct dpp_global * dpp,void * msg_ctx,u8 dpp_allowed_roles,int qr_mutual,struct dpp_bootstrap_info * peer_bi,struct dpp_bootstrap_info * own_bi,unsigned int freq,const u8 * hdr,const u8 * attr_start,size_t attr_len)668 dpp_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 	EVP_PKEY *pi = NULL;
675 	EVP_PKEY_CTX *ctx = NULL;
676 	size_t secret_len;
677 	const u8 *addr[2];
678 	size_t len[2];
679 	u8 *unwrapped = NULL;
680 	size_t unwrapped_len = 0;
681 	const u8 *wrapped_data, *i_proto, *i_nonce, *i_capab, *i_bootstrap,
682 		*channel;
683 	u16 wrapped_data_len, i_proto_len, i_nonce_len, i_capab_len,
684 		i_bootstrap_len, channel_len;
685 	struct dpp_authentication *auth = NULL;
686 #ifdef CONFIG_DPP2
687 	const u8 *version;
688 	u16 version_len;
689 #endif /* CONFIG_DPP2 */
690 
691 #ifdef CONFIG_TESTING_OPTIONS
692 	if (dpp_test == DPP_TEST_STOP_AT_AUTH_REQ) {
693 		wpa_printf(MSG_INFO,
694 			   "DPP: TESTING - stop at Authentication Request");
695 		return NULL;
696 	}
697 #endif /* CONFIG_TESTING_OPTIONS */
698 
699 	wrapped_data = dpp_get_attr(attr_start, attr_len, DPP_ATTR_WRAPPED_DATA,
700 				    &wrapped_data_len);
701 	if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) {
702 		wpa_msg(msg_ctx, MSG_INFO, DPP_EVENT_FAIL
703 			"Missing or invalid required Wrapped Data attribute");
704 		return NULL;
705 	}
706 	wpa_hexdump(MSG_MSGDUMP, "DPP: Wrapped Data",
707 		    wrapped_data, wrapped_data_len);
708 	attr_len = wrapped_data - 4 - attr_start;
709 
710 	auth = dpp_alloc_auth(dpp, msg_ctx);
711 	if (!auth)
712 		goto fail;
713 	if (peer_bi && peer_bi->configurator_params &&
714 	    dpp_set_configurator(auth, peer_bi->configurator_params) < 0)
715 		goto fail;
716 	auth->peer_bi = peer_bi;
717 	auth->own_bi = own_bi;
718 	auth->curve = own_bi->curve;
719 	auth->curr_freq = freq;
720 
721 	auth->peer_version = 1; /* default to the first version */
722 #ifdef CONFIG_DPP2
723 	version = dpp_get_attr(attr_start, attr_len, DPP_ATTR_PROTOCOL_VERSION,
724 			       &version_len);
725 	if (version && DPP_VERSION > 1) {
726 		if (version_len < 1 || version[0] == 0) {
727 			dpp_auth_fail(auth,
728 				      "Invalid Protocol Version attribute");
729 			goto fail;
730 		}
731 		auth->peer_version = version[0];
732 		wpa_printf(MSG_DEBUG, "DPP: Peer protocol version %u",
733 			   auth->peer_version);
734 	}
735 #endif /* CONFIG_DPP2 */
736 
737 	channel = dpp_get_attr(attr_start, attr_len, DPP_ATTR_CHANNEL,
738 			       &channel_len);
739 	if (channel) {
740 		int neg_freq;
741 
742 		if (channel_len < 2) {
743 			dpp_auth_fail(auth, "Too short Channel attribute");
744 			goto fail;
745 		}
746 
747 		neg_freq = ieee80211_chan_to_freq(NULL, channel[0], channel[1]);
748 		wpa_printf(MSG_DEBUG,
749 			   "DPP: Initiator requested different channel for negotiation: op_class=%u channel=%u --> freq=%d",
750 			   channel[0], channel[1], neg_freq);
751 		if (neg_freq < 0) {
752 			dpp_auth_fail(auth,
753 				      "Unsupported Channel attribute value");
754 			goto fail;
755 		}
756 
757 		if (auth->curr_freq != (unsigned int) neg_freq) {
758 			wpa_printf(MSG_DEBUG,
759 				   "DPP: Changing negotiation channel from %u MHz to %u MHz",
760 				   freq, neg_freq);
761 			auth->curr_freq = neg_freq;
762 		}
763 	}
764 
765 	i_proto = dpp_get_attr(attr_start, attr_len, DPP_ATTR_I_PROTOCOL_KEY,
766 			       &i_proto_len);
767 	if (!i_proto) {
768 		dpp_auth_fail(auth,
769 			      "Missing required Initiator Protocol Key attribute");
770 		goto fail;
771 	}
772 	wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Protocol Key",
773 		    i_proto, i_proto_len);
774 
775 	/* M = bR * PI */
776 	pi = dpp_set_pubkey_point(own_bi->pubkey, i_proto, i_proto_len);
777 	if (!pi) {
778 		dpp_auth_fail(auth, "Invalid Initiator Protocol Key");
779 		goto fail;
780 	}
781 	dpp_debug_print_key("Peer (Initiator) Protocol Key", pi);
782 
783 	if (dpp_ecdh(own_bi->pubkey, pi, auth->Mx, &secret_len) < 0)
784 		goto fail;
785 	auth->secret_len = secret_len;
786 
787 	wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (M.x)",
788 			auth->Mx, auth->secret_len);
789 	auth->Mx_len = auth->secret_len;
790 
791 	if (dpp_derive_k1(auth->Mx, auth->secret_len, auth->k1,
792 			  auth->curve->hash_len) < 0)
793 		goto fail;
794 
795 	addr[0] = hdr;
796 	len[0] = DPP_HDR_LEN;
797 	addr[1] = attr_start;
798 	len[1] = attr_len;
799 	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
800 	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
801 	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
802 		    wrapped_data, wrapped_data_len);
803 	unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
804 	unwrapped = os_malloc(unwrapped_len);
805 	if (!unwrapped)
806 		goto fail;
807 	if (aes_siv_decrypt(auth->k1, auth->curve->hash_len,
808 			    wrapped_data, wrapped_data_len,
809 			    2, addr, len, unwrapped) < 0) {
810 		dpp_auth_fail(auth, "AES-SIV decryption failed");
811 		goto fail;
812 	}
813 	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
814 		    unwrapped, unwrapped_len);
815 
816 	if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
817 		dpp_auth_fail(auth, "Invalid attribute in unwrapped data");
818 		goto fail;
819 	}
820 
821 	i_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_NONCE,
822 			       &i_nonce_len);
823 	if (!i_nonce || i_nonce_len != auth->curve->nonce_len) {
824 		dpp_auth_fail(auth, "Missing or invalid I-nonce");
825 		goto fail;
826 	}
827 	wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", i_nonce, i_nonce_len);
828 	os_memcpy(auth->i_nonce, i_nonce, i_nonce_len);
829 
830 	i_capab = dpp_get_attr(unwrapped, unwrapped_len,
831 			       DPP_ATTR_I_CAPABILITIES,
832 			       &i_capab_len);
833 	if (!i_capab || i_capab_len < 1) {
834 		dpp_auth_fail(auth, "Missing or invalid I-capabilities");
835 		goto fail;
836 	}
837 	auth->i_capab = i_capab[0];
838 	wpa_printf(MSG_DEBUG, "DPP: I-capabilities: 0x%02x", auth->i_capab);
839 
840 	bin_clear_free(unwrapped, unwrapped_len);
841 	unwrapped = NULL;
842 
843 	switch (auth->i_capab & DPP_CAPAB_ROLE_MASK) {
844 	case DPP_CAPAB_ENROLLEE:
845 		if (!(dpp_allowed_roles & DPP_CAPAB_CONFIGURATOR)) {
846 			wpa_printf(MSG_DEBUG,
847 				   "DPP: Local policy does not allow Configurator role");
848 			goto not_compatible;
849 		}
850 		wpa_printf(MSG_DEBUG, "DPP: Acting as Configurator");
851 		auth->configurator = 1;
852 		break;
853 	case DPP_CAPAB_CONFIGURATOR:
854 		if (!(dpp_allowed_roles & DPP_CAPAB_ENROLLEE)) {
855 			wpa_printf(MSG_DEBUG,
856 				   "DPP: Local policy does not allow Enrollee role");
857 			goto not_compatible;
858 		}
859 		wpa_printf(MSG_DEBUG, "DPP: Acting as Enrollee");
860 		auth->configurator = 0;
861 		break;
862 	case DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE:
863 		if (dpp_allowed_roles & DPP_CAPAB_ENROLLEE) {
864 			wpa_printf(MSG_DEBUG, "DPP: Acting as Enrollee");
865 			auth->configurator = 0;
866 		} else if (dpp_allowed_roles & DPP_CAPAB_CONFIGURATOR) {
867 			wpa_printf(MSG_DEBUG, "DPP: Acting as Configurator");
868 			auth->configurator = 1;
869 		} else {
870 			wpa_printf(MSG_DEBUG,
871 				   "DPP: Local policy does not allow Configurator/Enrollee role");
872 			goto not_compatible;
873 		}
874 		break;
875 	default:
876 		wpa_printf(MSG_DEBUG, "DPP: Unexpected role in I-capabilities");
877 		wpa_msg(auth->msg_ctx, MSG_INFO,
878 			DPP_EVENT_FAIL "Invalid role in I-capabilities 0x%02x",
879 			auth->i_capab & DPP_CAPAB_ROLE_MASK);
880 		goto fail;
881 	}
882 
883 	auth->peer_protocol_key = pi;
884 	pi = NULL;
885 	if (qr_mutual && !peer_bi && own_bi->type == DPP_BOOTSTRAP_QR_CODE) {
886 		char hex[SHA256_MAC_LEN * 2 + 1];
887 
888 		wpa_printf(MSG_DEBUG,
889 			   "DPP: Mutual authentication required with QR Codes, but peer info is not yet available - request more time");
890 		if (dpp_auth_build_resp_status(auth,
891 					       DPP_STATUS_RESPONSE_PENDING) < 0)
892 			goto fail;
893 		i_bootstrap = dpp_get_attr(attr_start, attr_len,
894 					   DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
895 					   &i_bootstrap_len);
896 		if (i_bootstrap && i_bootstrap_len == SHA256_MAC_LEN) {
897 			auth->response_pending = 1;
898 			os_memcpy(auth->waiting_pubkey_hash,
899 				  i_bootstrap, i_bootstrap_len);
900 			wpa_snprintf_hex(hex, sizeof(hex), i_bootstrap,
901 					 i_bootstrap_len);
902 		} else {
903 			hex[0] = '\0';
904 		}
905 
906 		wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_SCAN_PEER_QR_CODE
907 			"%s", hex);
908 		return auth;
909 	}
910 	if (dpp_auth_build_resp_ok(auth) < 0)
911 		goto fail;
912 
913 	return auth;
914 
915 not_compatible:
916 	wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_NOT_COMPATIBLE
917 		"i-capab=0x%02x", auth->i_capab);
918 	if (dpp_allowed_roles & DPP_CAPAB_CONFIGURATOR)
919 		auth->configurator = 1;
920 	else
921 		auth->configurator = 0;
922 	auth->peer_protocol_key = pi;
923 	pi = NULL;
924 	if (dpp_auth_build_resp_status(auth, DPP_STATUS_NOT_COMPATIBLE) < 0)
925 		goto fail;
926 
927 	auth->remove_on_tx_status = 1;
928 	return auth;
929 fail:
930 	bin_clear_free(unwrapped, unwrapped_len);
931 	EVP_PKEY_free(pi);
932 	EVP_PKEY_CTX_free(ctx);
933 	dpp_auth_deinit(auth);
934 	return NULL;
935 }
936 
937 
dpp_notify_new_qr_code(struct dpp_authentication * auth,struct dpp_bootstrap_info * peer_bi)938 int dpp_notify_new_qr_code(struct dpp_authentication *auth,
939 			   struct dpp_bootstrap_info *peer_bi)
940 {
941 	if (!auth || !auth->response_pending ||
942 	    os_memcmp(auth->waiting_pubkey_hash, peer_bi->pubkey_hash,
943 		      SHA256_MAC_LEN) != 0)
944 		return 0;
945 
946 	wpa_printf(MSG_DEBUG,
947 		   "DPP: New scanned QR Code has matching public key that was needed to continue DPP Authentication exchange with "
948 		   MACSTR, MAC2STR(auth->peer_mac_addr));
949 	auth->peer_bi = peer_bi;
950 
951 	if (dpp_auth_build_resp_ok(auth) < 0)
952 		return -1;
953 
954 	return 1;
955 }
956 
957 
dpp_auth_build_conf(struct dpp_authentication * auth,enum dpp_status_error status)958 static struct wpabuf * dpp_auth_build_conf(struct dpp_authentication *auth,
959 					   enum dpp_status_error status)
960 {
961 	struct wpabuf *msg;
962 	u8 i_auth[4 + DPP_MAX_HASH_LEN];
963 	size_t i_auth_len;
964 	u8 r_nonce[4 + DPP_MAX_NONCE_LEN];
965 	size_t r_nonce_len;
966 	const u8 *addr[2];
967 	size_t len[2], attr_len;
968 	u8 *wrapped_i_auth;
969 	u8 *wrapped_r_nonce;
970 	u8 *attr_start, *attr_end;
971 	const u8 *r_pubkey_hash, *i_pubkey_hash;
972 #ifdef CONFIG_TESTING_OPTIONS
973 	u8 test_hash[SHA256_MAC_LEN];
974 #endif /* CONFIG_TESTING_OPTIONS */
975 
976 	wpa_printf(MSG_DEBUG, "DPP: Build Authentication Confirmation");
977 
978 	i_auth_len = 4 + auth->curve->hash_len;
979 	r_nonce_len = 4 + auth->curve->nonce_len;
980 	/* Build DPP Authentication Confirmation frame attributes */
981 	attr_len = 4 + 1 + 2 * (4 + SHA256_MAC_LEN) +
982 		4 + i_auth_len + r_nonce_len + AES_BLOCK_SIZE;
983 #ifdef CONFIG_TESTING_OPTIONS
984 	if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_CONF)
985 		attr_len += 5;
986 #endif /* CONFIG_TESTING_OPTIONS */
987 	msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_CONF, attr_len);
988 	if (!msg)
989 		goto fail;
990 
991 	attr_start = wpabuf_put(msg, 0);
992 
993 	r_pubkey_hash = auth->peer_bi->pubkey_hash;
994 	if (auth->own_bi)
995 		i_pubkey_hash = auth->own_bi->pubkey_hash;
996 	else
997 		i_pubkey_hash = NULL;
998 
999 #ifdef CONFIG_TESTING_OPTIONS
1000 	if (dpp_test == DPP_TEST_NO_STATUS_AUTH_CONF) {
1001 		wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
1002 		goto skip_status;
1003 	} else if (dpp_test == DPP_TEST_INVALID_STATUS_AUTH_CONF) {
1004 		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status");
1005 		status = 254;
1006 	}
1007 #endif /* CONFIG_TESTING_OPTIONS */
1008 
1009 	/* DPP Status */
1010 	dpp_build_attr_status(msg, status);
1011 
1012 #ifdef CONFIG_TESTING_OPTIONS
1013 skip_status:
1014 	if (dpp_test == DPP_TEST_NO_R_BOOTSTRAP_KEY_HASH_AUTH_CONF) {
1015 		wpa_printf(MSG_INFO, "DPP: TESTING - no R-Bootstrap Key Hash");
1016 		r_pubkey_hash = NULL;
1017 	} else if (dpp_test ==
1018 		   DPP_TEST_INVALID_R_BOOTSTRAP_KEY_HASH_AUTH_CONF) {
1019 		wpa_printf(MSG_INFO,
1020 			   "DPP: TESTING - invalid R-Bootstrap Key Hash");
1021 		os_memcpy(test_hash, r_pubkey_hash, SHA256_MAC_LEN);
1022 		test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
1023 		r_pubkey_hash = test_hash;
1024 	} else if (dpp_test == DPP_TEST_NO_I_BOOTSTRAP_KEY_HASH_AUTH_CONF) {
1025 		wpa_printf(MSG_INFO, "DPP: TESTING - no I-Bootstrap Key Hash");
1026 		i_pubkey_hash = NULL;
1027 	} else if (dpp_test ==
1028 		   DPP_TEST_INVALID_I_BOOTSTRAP_KEY_HASH_AUTH_CONF) {
1029 		wpa_printf(MSG_INFO,
1030 			   "DPP: TESTING - invalid I-Bootstrap Key Hash");
1031 		if (i_pubkey_hash)
1032 			os_memcpy(test_hash, i_pubkey_hash, SHA256_MAC_LEN);
1033 		else
1034 			os_memset(test_hash, 0, SHA256_MAC_LEN);
1035 		test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
1036 		i_pubkey_hash = test_hash;
1037 	}
1038 #endif /* CONFIG_TESTING_OPTIONS */
1039 
1040 	/* Responder Bootstrapping Key Hash */
1041 	dpp_build_attr_r_bootstrap_key_hash(msg, r_pubkey_hash);
1042 
1043 	/* Initiator Bootstrapping Key Hash (mutual authentication) */
1044 	dpp_build_attr_i_bootstrap_key_hash(msg, i_pubkey_hash);
1045 
1046 #ifdef CONFIG_TESTING_OPTIONS
1047 	if (dpp_test == DPP_TEST_NO_WRAPPED_DATA_AUTH_CONF)
1048 		goto skip_wrapped_data;
1049 	if (dpp_test == DPP_TEST_NO_I_AUTH_AUTH_CONF)
1050 		i_auth_len = 0;
1051 #endif /* CONFIG_TESTING_OPTIONS */
1052 
1053 	attr_end = wpabuf_put(msg, 0);
1054 
1055 	/* OUI, OUI type, Crypto Suite, DPP frame type */
1056 	addr[0] = wpabuf_head_u8(msg) + 2;
1057 	len[0] = 3 + 1 + 1 + 1;
1058 	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
1059 
1060 	/* Attributes before Wrapped Data */
1061 	addr[1] = attr_start;
1062 	len[1] = attr_end - attr_start;
1063 	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
1064 
1065 	if (status == DPP_STATUS_OK) {
1066 		/* I-auth wrapped with ke */
1067 		wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
1068 		wpabuf_put_le16(msg, i_auth_len + AES_BLOCK_SIZE);
1069 		wrapped_i_auth = wpabuf_put(msg, i_auth_len + AES_BLOCK_SIZE);
1070 
1071 #ifdef CONFIG_TESTING_OPTIONS
1072 		if (dpp_test == DPP_TEST_NO_I_AUTH_AUTH_CONF)
1073 			goto skip_i_auth;
1074 #endif /* CONFIG_TESTING_OPTIONS */
1075 
1076 		/* I-auth = H(R-nonce | I-nonce | PR.x | PI.x | BR.x | [BI.x |]
1077 		 *	      1) */
1078 		WPA_PUT_LE16(i_auth, DPP_ATTR_I_AUTH_TAG);
1079 		WPA_PUT_LE16(&i_auth[2], auth->curve->hash_len);
1080 		if (dpp_gen_i_auth(auth, i_auth + 4) < 0)
1081 			goto fail;
1082 
1083 #ifdef CONFIG_TESTING_OPTIONS
1084 		if (dpp_test == DPP_TEST_I_AUTH_MISMATCH_AUTH_CONF) {
1085 			wpa_printf(MSG_INFO, "DPP: TESTING - I-auth mismatch");
1086 			i_auth[4 + auth->curve->hash_len / 2] ^= 0x01;
1087 		}
1088 skip_i_auth:
1089 #endif /* CONFIG_TESTING_OPTIONS */
1090 		if (aes_siv_encrypt(auth->ke, auth->curve->hash_len,
1091 				    i_auth, i_auth_len,
1092 				    2, addr, len, wrapped_i_auth) < 0)
1093 			goto fail;
1094 		wpa_hexdump(MSG_DEBUG, "DPP: {I-auth}ke",
1095 			    wrapped_i_auth, i_auth_len + AES_BLOCK_SIZE);
1096 	} else {
1097 		/* R-nonce wrapped with k2 */
1098 		wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
1099 		wpabuf_put_le16(msg, r_nonce_len + AES_BLOCK_SIZE);
1100 		wrapped_r_nonce = wpabuf_put(msg, r_nonce_len + AES_BLOCK_SIZE);
1101 
1102 		WPA_PUT_LE16(r_nonce, DPP_ATTR_R_NONCE);
1103 		WPA_PUT_LE16(&r_nonce[2], auth->curve->nonce_len);
1104 		os_memcpy(r_nonce + 4, auth->r_nonce, auth->curve->nonce_len);
1105 
1106 		if (aes_siv_encrypt(auth->k2, auth->curve->hash_len,
1107 				    r_nonce, r_nonce_len,
1108 				    2, addr, len, wrapped_r_nonce) < 0)
1109 			goto fail;
1110 		wpa_hexdump(MSG_DEBUG, "DPP: {R-nonce}k2",
1111 			    wrapped_r_nonce, r_nonce_len + AES_BLOCK_SIZE);
1112 	}
1113 
1114 #ifdef CONFIG_TESTING_OPTIONS
1115 	if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_CONF) {
1116 		wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
1117 		dpp_build_attr_status(msg, DPP_STATUS_OK);
1118 	}
1119 skip_wrapped_data:
1120 #endif /* CONFIG_TESTING_OPTIONS */
1121 
1122 	wpa_hexdump_buf(MSG_DEBUG,
1123 			"DPP: Authentication Confirmation frame attributes",
1124 			msg);
1125 	if (status == DPP_STATUS_OK)
1126 		dpp_auth_success(auth);
1127 
1128 	return msg;
1129 
1130 fail:
1131 	wpabuf_free(msg);
1132 	return NULL;
1133 }
1134 
1135 
dpp_autogen_bootstrap_key(struct dpp_authentication * auth)1136 static int dpp_autogen_bootstrap_key(struct dpp_authentication *auth)
1137 {
1138 	struct dpp_bootstrap_info *bi;
1139 
1140 	if (auth->own_bi)
1141 		return 0; /* already generated */
1142 
1143 	bi = os_zalloc(sizeof(*bi));
1144 	if (!bi)
1145 		return -1;
1146 	bi->type = DPP_BOOTSTRAP_QR_CODE;
1147 	if (dpp_keygen(bi, auth->peer_bi->curve->name, NULL, 0) < 0 ||
1148 	    dpp_gen_uri(bi) < 0)
1149 		goto fail;
1150 	wpa_printf(MSG_DEBUG,
1151 		   "DPP: Auto-generated own bootstrapping key info: URI %s",
1152 		   bi->uri);
1153 
1154 	auth->tmp_own_bi = auth->own_bi = bi;
1155 
1156 	return 0;
1157 fail:
1158 	dpp_bootstrap_info_free(bi);
1159 	return -1;
1160 }
1161 
1162 
dpp_auth_init(struct dpp_global * dpp,void * msg_ctx,struct dpp_bootstrap_info * peer_bi,struct dpp_bootstrap_info * own_bi,u8 dpp_allowed_roles,unsigned int neg_freq,struct hostapd_hw_modes * own_modes,u16 num_modes)1163 struct dpp_authentication * dpp_auth_init(struct dpp_global *dpp, void *msg_ctx,
1164 					  struct dpp_bootstrap_info *peer_bi,
1165 					  struct dpp_bootstrap_info *own_bi,
1166 					  u8 dpp_allowed_roles,
1167 					  unsigned int neg_freq,
1168 					  struct hostapd_hw_modes *own_modes,
1169 					  u16 num_modes)
1170 {
1171 	struct dpp_authentication *auth;
1172 	size_t nonce_len;
1173 	size_t secret_len;
1174 	struct wpabuf *pi = NULL;
1175 	const u8 *r_pubkey_hash, *i_pubkey_hash;
1176 #ifdef CONFIG_TESTING_OPTIONS
1177 	u8 test_hash[SHA256_MAC_LEN];
1178 #endif /* CONFIG_TESTING_OPTIONS */
1179 
1180 	auth = dpp_alloc_auth(dpp, msg_ctx);
1181 	if (!auth)
1182 		return NULL;
1183 	if (peer_bi->configurator_params &&
1184 	    dpp_set_configurator(auth, peer_bi->configurator_params) < 0)
1185 		goto fail;
1186 	auth->initiator = 1;
1187 	auth->waiting_auth_resp = 1;
1188 	auth->allowed_roles = dpp_allowed_roles;
1189 	auth->configurator = !!(dpp_allowed_roles & DPP_CAPAB_CONFIGURATOR);
1190 	auth->peer_bi = peer_bi;
1191 	auth->own_bi = own_bi;
1192 	auth->curve = peer_bi->curve;
1193 
1194 	if (dpp_autogen_bootstrap_key(auth) < 0 ||
1195 	    dpp_prepare_channel_list(auth, neg_freq, own_modes, num_modes) < 0)
1196 		goto fail;
1197 
1198 #ifdef CONFIG_TESTING_OPTIONS
1199 	if (dpp_nonce_override_len > 0) {
1200 		wpa_printf(MSG_INFO, "DPP: TESTING - override I-nonce");
1201 		nonce_len = dpp_nonce_override_len;
1202 		os_memcpy(auth->i_nonce, dpp_nonce_override, nonce_len);
1203 	} else {
1204 		nonce_len = auth->curve->nonce_len;
1205 		if (random_get_bytes(auth->i_nonce, nonce_len)) {
1206 			wpa_printf(MSG_ERROR,
1207 				   "DPP: Failed to generate I-nonce");
1208 			goto fail;
1209 		}
1210 	}
1211 #else /* CONFIG_TESTING_OPTIONS */
1212 	nonce_len = auth->curve->nonce_len;
1213 	if (random_get_bytes(auth->i_nonce, nonce_len)) {
1214 		wpa_printf(MSG_ERROR, "DPP: Failed to generate I-nonce");
1215 		goto fail;
1216 	}
1217 #endif /* CONFIG_TESTING_OPTIONS */
1218 	wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", auth->i_nonce, nonce_len);
1219 
1220 #ifdef CONFIG_TESTING_OPTIONS
1221 	if (dpp_protocol_key_override_len) {
1222 		const struct dpp_curve_params *tmp_curve;
1223 
1224 		wpa_printf(MSG_INFO,
1225 			   "DPP: TESTING - override protocol key");
1226 		auth->own_protocol_key = dpp_set_keypair(
1227 			&tmp_curve, dpp_protocol_key_override,
1228 			dpp_protocol_key_override_len);
1229 	} else {
1230 		auth->own_protocol_key = dpp_gen_keypair(auth->curve);
1231 	}
1232 #else /* CONFIG_TESTING_OPTIONS */
1233 	auth->own_protocol_key = dpp_gen_keypair(auth->curve);
1234 #endif /* CONFIG_TESTING_OPTIONS */
1235 	if (!auth->own_protocol_key)
1236 		goto fail;
1237 
1238 	pi = dpp_get_pubkey_point(auth->own_protocol_key, 0);
1239 	if (!pi)
1240 		goto fail;
1241 
1242 	/* ECDH: M = pI * BR */
1243 	if (dpp_ecdh(auth->own_protocol_key, auth->peer_bi->pubkey,
1244 		     auth->Mx, &secret_len) < 0)
1245 		goto fail;
1246 	auth->secret_len = secret_len;
1247 
1248 	wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (M.x)",
1249 			auth->Mx, auth->secret_len);
1250 	auth->Mx_len = auth->secret_len;
1251 
1252 	if (dpp_derive_k1(auth->Mx, auth->secret_len, auth->k1,
1253 			  auth->curve->hash_len) < 0)
1254 		goto fail;
1255 
1256 	r_pubkey_hash = auth->peer_bi->pubkey_hash;
1257 	i_pubkey_hash = auth->own_bi->pubkey_hash;
1258 
1259 #ifdef CONFIG_TESTING_OPTIONS
1260 	if (dpp_test == DPP_TEST_NO_R_BOOTSTRAP_KEY_HASH_AUTH_REQ) {
1261 		wpa_printf(MSG_INFO, "DPP: TESTING - no R-Bootstrap Key Hash");
1262 		r_pubkey_hash = NULL;
1263 	} else if (dpp_test == DPP_TEST_INVALID_R_BOOTSTRAP_KEY_HASH_AUTH_REQ) {
1264 		wpa_printf(MSG_INFO,
1265 			   "DPP: TESTING - invalid R-Bootstrap Key Hash");
1266 		os_memcpy(test_hash, r_pubkey_hash, SHA256_MAC_LEN);
1267 		test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
1268 		r_pubkey_hash = test_hash;
1269 	} else if (dpp_test == DPP_TEST_NO_I_BOOTSTRAP_KEY_HASH_AUTH_REQ) {
1270 		wpa_printf(MSG_INFO, "DPP: TESTING - no I-Bootstrap Key Hash");
1271 		i_pubkey_hash = NULL;
1272 	} else if (dpp_test == DPP_TEST_INVALID_I_BOOTSTRAP_KEY_HASH_AUTH_REQ) {
1273 		wpa_printf(MSG_INFO,
1274 			   "DPP: TESTING - invalid I-Bootstrap Key Hash");
1275 		os_memcpy(test_hash, i_pubkey_hash, SHA256_MAC_LEN);
1276 		test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
1277 		i_pubkey_hash = test_hash;
1278 	} else if (dpp_test == DPP_TEST_NO_I_PROTO_KEY_AUTH_REQ) {
1279 		wpa_printf(MSG_INFO, "DPP: TESTING - no I-Proto Key");
1280 		wpabuf_free(pi);
1281 		pi = NULL;
1282 	} else if (dpp_test == DPP_TEST_INVALID_I_PROTO_KEY_AUTH_REQ) {
1283 		wpa_printf(MSG_INFO, "DPP: TESTING - invalid I-Proto Key");
1284 		wpabuf_free(pi);
1285 		pi = wpabuf_alloc(2 * auth->curve->prime_len);
1286 		if (!pi || dpp_test_gen_invalid_key(pi, auth->curve) < 0)
1287 			goto fail;
1288 	}
1289 #endif /* CONFIG_TESTING_OPTIONS */
1290 
1291 	if (neg_freq && auth->num_freq == 1 && auth->freq[0] == neg_freq)
1292 		neg_freq = 0;
1293 	auth->req_msg = dpp_auth_build_req(auth, pi, nonce_len, r_pubkey_hash,
1294 					   i_pubkey_hash, neg_freq);
1295 	if (!auth->req_msg)
1296 		goto fail;
1297 
1298 out:
1299 	wpabuf_free(pi);
1300 	return auth;
1301 fail:
1302 	dpp_auth_deinit(auth);
1303 	auth = NULL;
1304 	goto out;
1305 }
1306 static void
dpp_auth_resp_rx_status(struct dpp_authentication * auth,const u8 * hdr,const u8 * attr_start,size_t attr_len,const u8 * wrapped_data,u16 wrapped_data_len,enum dpp_status_error status)1307 dpp_auth_resp_rx_status(struct dpp_authentication *auth, const u8 *hdr,
1308 			const u8 *attr_start, size_t attr_len,
1309 			const u8 *wrapped_data, u16 wrapped_data_len,
1310 			enum dpp_status_error status)
1311 {
1312 	const u8 *addr[2];
1313 	size_t len[2];
1314 	u8 *unwrapped = NULL;
1315 	size_t unwrapped_len = 0;
1316 	const u8 *i_nonce, *r_capab;
1317 	u16 i_nonce_len, r_capab_len;
1318 
1319 	if (status == DPP_STATUS_NOT_COMPATIBLE) {
1320 		wpa_printf(MSG_DEBUG,
1321 			   "DPP: Responder reported incompatible roles");
1322 	} else if (status == DPP_STATUS_RESPONSE_PENDING) {
1323 		wpa_printf(MSG_DEBUG,
1324 			   "DPP: Responder reported more time needed");
1325 	} else {
1326 		wpa_printf(MSG_DEBUG,
1327 			   "DPP: Responder reported failure (status %d)",
1328 			   status);
1329 		dpp_auth_fail(auth, "Responder reported failure");
1330 		return;
1331 	}
1332 
1333 	addr[0] = hdr;
1334 	len[0] = DPP_HDR_LEN;
1335 	addr[1] = attr_start;
1336 	len[1] = attr_len;
1337 	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
1338 	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
1339 	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
1340 		    wrapped_data, wrapped_data_len);
1341 	unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
1342 	unwrapped = os_malloc(unwrapped_len);
1343 	if (!unwrapped)
1344 		goto fail;
1345 	if (aes_siv_decrypt(auth->k1, auth->curve->hash_len,
1346 			    wrapped_data, wrapped_data_len,
1347 			    2, addr, len, unwrapped) < 0) {
1348 		dpp_auth_fail(auth, "AES-SIV decryption failed");
1349 		goto fail;
1350 	}
1351 	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
1352 		    unwrapped, unwrapped_len);
1353 
1354 	if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
1355 		dpp_auth_fail(auth, "Invalid attribute in unwrapped data");
1356 		goto fail;
1357 	}
1358 
1359 	i_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_NONCE,
1360 			       &i_nonce_len);
1361 	if (!i_nonce || i_nonce_len != auth->curve->nonce_len) {
1362 		dpp_auth_fail(auth, "Missing or invalid I-nonce");
1363 		goto fail;
1364 	}
1365 	wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", i_nonce, i_nonce_len);
1366 	if (os_memcmp(auth->i_nonce, i_nonce, i_nonce_len) != 0) {
1367 		dpp_auth_fail(auth, "I-nonce mismatch");
1368 		goto fail;
1369 	}
1370 
1371 	r_capab = dpp_get_attr(unwrapped, unwrapped_len,
1372 			       DPP_ATTR_R_CAPABILITIES,
1373 			       &r_capab_len);
1374 	if (!r_capab || r_capab_len < 1) {
1375 		dpp_auth_fail(auth, "Missing or invalid R-capabilities");
1376 		goto fail;
1377 	}
1378 	auth->r_capab = r_capab[0];
1379 	wpa_printf(MSG_DEBUG, "DPP: R-capabilities: 0x%02x", auth->r_capab);
1380 	if (status == DPP_STATUS_NOT_COMPATIBLE) {
1381 		wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_NOT_COMPATIBLE
1382 			"r-capab=0x%02x", auth->r_capab);
1383 	} else if (status == DPP_STATUS_RESPONSE_PENDING) {
1384 		u8 role = auth->r_capab & DPP_CAPAB_ROLE_MASK;
1385 
1386 		if ((auth->configurator && role != DPP_CAPAB_ENROLLEE) ||
1387 		    (!auth->configurator && role != DPP_CAPAB_CONFIGURATOR)) {
1388 			wpa_msg(auth->msg_ctx, MSG_INFO,
1389 				DPP_EVENT_FAIL "Unexpected role in R-capabilities 0x%02x",
1390 				role);
1391 		} else {
1392 			wpa_printf(MSG_DEBUG,
1393 				   "DPP: Continue waiting for full DPP Authentication Response");
1394 			wpa_msg(auth->msg_ctx, MSG_INFO,
1395 				DPP_EVENT_RESPONSE_PENDING "%s",
1396 				auth->tmp_own_bi ? auth->tmp_own_bi->uri : "");
1397 		}
1398 	}
1399 fail:
1400 	bin_clear_free(unwrapped, unwrapped_len);
1401 }
1402 
1403 
1404 struct wpabuf *
dpp_auth_resp_rx(struct dpp_authentication * auth,const u8 * hdr,const u8 * attr_start,size_t attr_len)1405 dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr,
1406 		 const u8 *attr_start, size_t attr_len)
1407 {
1408 	EVP_PKEY *pr;
1409 	size_t secret_len;
1410 	const u8 *addr[2];
1411 	size_t len[2];
1412 	u8 *unwrapped = NULL, *unwrapped2 = NULL;
1413 	size_t unwrapped_len = 0, unwrapped2_len = 0;
1414 	const u8 *r_bootstrap, *i_bootstrap, *wrapped_data, *status, *r_proto,
1415 		*r_nonce, *i_nonce, *r_capab, *wrapped2, *r_auth;
1416 	u16 r_bootstrap_len, i_bootstrap_len, wrapped_data_len, status_len,
1417 		r_proto_len, r_nonce_len, i_nonce_len, r_capab_len,
1418 		wrapped2_len, r_auth_len;
1419 	u8 r_auth2[DPP_MAX_HASH_LEN];
1420 	u8 role;
1421 #ifdef CONFIG_DPP2
1422 	const u8 *version;
1423 	u16 version_len;
1424 #endif /* CONFIG_DPP2 */
1425 
1426 #ifdef CONFIG_TESTING_OPTIONS
1427 	if (dpp_test == DPP_TEST_STOP_AT_AUTH_RESP) {
1428 		wpa_printf(MSG_INFO,
1429 			   "DPP: TESTING - stop at Authentication Response");
1430 		return NULL;
1431 	}
1432 #endif /* CONFIG_TESTING_OPTIONS */
1433 
1434 	if (!auth->initiator || !auth->peer_bi || auth->reconfig) {
1435 		dpp_auth_fail(auth, "Unexpected Authentication Response");
1436 		return NULL;
1437 	}
1438 
1439 	auth->waiting_auth_resp = 0;
1440 
1441 	wrapped_data = dpp_get_attr(attr_start, attr_len, DPP_ATTR_WRAPPED_DATA,
1442 				    &wrapped_data_len);
1443 	if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) {
1444 		dpp_auth_fail(auth,
1445 			      "Missing or invalid required Wrapped Data attribute");
1446 		return NULL;
1447 	}
1448 	wpa_hexdump(MSG_DEBUG, "DPP: Wrapped data",
1449 		    wrapped_data, wrapped_data_len);
1450 
1451 	attr_len = wrapped_data - 4 - attr_start;
1452 
1453 	r_bootstrap = dpp_get_attr(attr_start, attr_len,
1454 				   DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
1455 				   &r_bootstrap_len);
1456 	if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
1457 		dpp_auth_fail(auth,
1458 			      "Missing or invalid required Responder Bootstrapping Key Hash attribute");
1459 		return NULL;
1460 	}
1461 	wpa_hexdump(MSG_DEBUG, "DPP: Responder Bootstrapping Key Hash",
1462 		    r_bootstrap, r_bootstrap_len);
1463 	if (os_memcmp(r_bootstrap, auth->peer_bi->pubkey_hash,
1464 		      SHA256_MAC_LEN) != 0) {
1465 		dpp_auth_fail(auth,
1466 			      "Unexpected Responder Bootstrapping Key Hash value");
1467 		wpa_hexdump(MSG_DEBUG,
1468 			    "DPP: Expected Responder Bootstrapping Key Hash",
1469 			    auth->peer_bi->pubkey_hash, SHA256_MAC_LEN);
1470 		return NULL;
1471 	}
1472 
1473 	i_bootstrap = dpp_get_attr(attr_start, attr_len,
1474 				   DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
1475 				   &i_bootstrap_len);
1476 	if (i_bootstrap) {
1477 		if (i_bootstrap_len != SHA256_MAC_LEN) {
1478 			dpp_auth_fail(auth,
1479 				      "Invalid Initiator Bootstrapping Key Hash attribute");
1480 			return NULL;
1481 		}
1482 		wpa_hexdump(MSG_MSGDUMP,
1483 			    "DPP: Initiator Bootstrapping Key Hash",
1484 			    i_bootstrap, i_bootstrap_len);
1485 		if (!auth->own_bi ||
1486 		    os_memcmp(i_bootstrap, auth->own_bi->pubkey_hash,
1487 			      SHA256_MAC_LEN) != 0) {
1488 			dpp_auth_fail(auth,
1489 				      "Initiator Bootstrapping Key Hash attribute did not match");
1490 			return NULL;
1491 		}
1492 	} else if (auth->own_bi && auth->own_bi->type == DPP_BOOTSTRAP_PKEX) {
1493 		/* PKEX bootstrapping mandates use of mutual authentication */
1494 		dpp_auth_fail(auth,
1495 			      "Missing Initiator Bootstrapping Key Hash attribute");
1496 		return NULL;
1497 	} else if (auth->own_bi &&
1498 		   auth->own_bi->type == DPP_BOOTSTRAP_NFC_URI &&
1499 		   auth->own_bi->nfc_negotiated) {
1500 		/* NFC negotiated connection handover bootstrapping mandates
1501 		 * use of mutual authentication */
1502 		dpp_auth_fail(auth,
1503 			      "Missing Initiator Bootstrapping Key Hash attribute");
1504 		return NULL;
1505 	}
1506 
1507 	auth->peer_version = 1; /* default to the first version */
1508 #ifdef CONFIG_DPP2
1509 	version = dpp_get_attr(attr_start, attr_len, DPP_ATTR_PROTOCOL_VERSION,
1510 			       &version_len);
1511 	if (version && DPP_VERSION > 1) {
1512 		if (version_len < 1 || version[0] == 0) {
1513 			dpp_auth_fail(auth,
1514 				      "Invalid Protocol Version attribute");
1515 			return NULL;
1516 		}
1517 		auth->peer_version = version[0];
1518 		wpa_printf(MSG_DEBUG, "DPP: Peer protocol version %u",
1519 			   auth->peer_version);
1520 	}
1521 #endif /* CONFIG_DPP2 */
1522 
1523 	status = dpp_get_attr(attr_start, attr_len, DPP_ATTR_STATUS,
1524 			      &status_len);
1525 	if (!status || status_len < 1) {
1526 		dpp_auth_fail(auth,
1527 			      "Missing or invalid required DPP Status attribute");
1528 		return NULL;
1529 	}
1530 	wpa_printf(MSG_DEBUG, "DPP: Status %u", status[0]);
1531 	auth->auth_resp_status = status[0];
1532 	if (status[0] != DPP_STATUS_OK) {
1533 		dpp_auth_resp_rx_status(auth, hdr, attr_start,
1534 					attr_len, wrapped_data,
1535 					wrapped_data_len, status[0]);
1536 		return NULL;
1537 	}
1538 
1539 	if (!i_bootstrap && auth->own_bi) {
1540 		wpa_printf(MSG_DEBUG,
1541 			   "DPP: Responder decided not to use mutual authentication");
1542 		auth->own_bi = NULL;
1543 	}
1544 
1545 	wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_DIRECTION "mutual=%d",
1546 		auth->own_bi != NULL);
1547 
1548 	r_proto = dpp_get_attr(attr_start, attr_len, DPP_ATTR_R_PROTOCOL_KEY,
1549 			       &r_proto_len);
1550 	if (!r_proto) {
1551 		dpp_auth_fail(auth,
1552 			      "Missing required Responder Protocol Key attribute");
1553 		return NULL;
1554 	}
1555 	wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Protocol Key",
1556 		    r_proto, r_proto_len);
1557 
1558 	/* N = pI * PR */
1559 	pr = dpp_set_pubkey_point(auth->own_protocol_key, r_proto, r_proto_len);
1560 	if (!pr) {
1561 		dpp_auth_fail(auth, "Invalid Responder Protocol Key");
1562 		return NULL;
1563 	}
1564 	dpp_debug_print_key("Peer (Responder) Protocol Key", pr);
1565 
1566 	if (dpp_ecdh(auth->own_protocol_key, pr, auth->Nx, &secret_len) < 0) {
1567 		dpp_auth_fail(auth, "Failed to derive ECDH shared secret");
1568 		goto fail;
1569 	}
1570 	EVP_PKEY_free(auth->peer_protocol_key);
1571 	auth->peer_protocol_key = pr;
1572 	pr = NULL;
1573 
1574 	wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (N.x)",
1575 			auth->Nx, auth->secret_len);
1576 	auth->Nx_len = auth->secret_len;
1577 
1578 	if (dpp_derive_k2(auth->Nx, auth->secret_len, auth->k2,
1579 			  auth->curve->hash_len) < 0)
1580 		goto fail;
1581 
1582 	addr[0] = hdr;
1583 	len[0] = DPP_HDR_LEN;
1584 	addr[1] = attr_start;
1585 	len[1] = attr_len;
1586 	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
1587 	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
1588 	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
1589 		    wrapped_data, wrapped_data_len);
1590 	unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
1591 	unwrapped = os_malloc(unwrapped_len);
1592 	if (!unwrapped)
1593 		goto fail;
1594 	if (aes_siv_decrypt(auth->k2, auth->curve->hash_len,
1595 			    wrapped_data, wrapped_data_len,
1596 			    2, addr, len, unwrapped) < 0) {
1597 		dpp_auth_fail(auth, "AES-SIV decryption failed");
1598 		goto fail;
1599 	}
1600 	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
1601 		    unwrapped, unwrapped_len);
1602 
1603 	if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
1604 		dpp_auth_fail(auth, "Invalid attribute in unwrapped data");
1605 		goto fail;
1606 	}
1607 
1608 	r_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_R_NONCE,
1609 			       &r_nonce_len);
1610 	if (!r_nonce || r_nonce_len != auth->curve->nonce_len) {
1611 		dpp_auth_fail(auth, "DPP: Missing or invalid R-nonce");
1612 		goto fail;
1613 	}
1614 	wpa_hexdump(MSG_DEBUG, "DPP: R-nonce", r_nonce, r_nonce_len);
1615 	os_memcpy(auth->r_nonce, r_nonce, r_nonce_len);
1616 
1617 	i_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_NONCE,
1618 			       &i_nonce_len);
1619 	if (!i_nonce || i_nonce_len != auth->curve->nonce_len) {
1620 		dpp_auth_fail(auth, "Missing or invalid I-nonce");
1621 		goto fail;
1622 	}
1623 	wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", i_nonce, i_nonce_len);
1624 	if (os_memcmp(auth->i_nonce, i_nonce, i_nonce_len) != 0) {
1625 		dpp_auth_fail(auth, "I-nonce mismatch");
1626 		goto fail;
1627 	}
1628 
1629 	if (auth->own_bi) {
1630 		/* Mutual authentication */
1631 		if (dpp_auth_derive_l_initiator(auth) < 0)
1632 			goto fail;
1633 	}
1634 
1635 	r_capab = dpp_get_attr(unwrapped, unwrapped_len,
1636 			       DPP_ATTR_R_CAPABILITIES,
1637 			       &r_capab_len);
1638 	if (!r_capab || r_capab_len < 1) {
1639 		dpp_auth_fail(auth, "Missing or invalid R-capabilities");
1640 		goto fail;
1641 	}
1642 	auth->r_capab = r_capab[0];
1643 	wpa_printf(MSG_DEBUG, "DPP: R-capabilities: 0x%02x", auth->r_capab);
1644 	role = auth->r_capab & DPP_CAPAB_ROLE_MASK;
1645 	if ((auth->allowed_roles ==
1646 	     (DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE)) &&
1647 	    (role == DPP_CAPAB_CONFIGURATOR || role == DPP_CAPAB_ENROLLEE)) {
1648 		/* Peer selected its role, so move from "either role" to the
1649 		 * role that is compatible with peer's selection. */
1650 		auth->configurator = role == DPP_CAPAB_ENROLLEE;
1651 		wpa_printf(MSG_DEBUG, "DPP: Acting as %s",
1652 			   auth->configurator ? "Configurator" : "Enrollee");
1653 	} else if ((auth->configurator && role != DPP_CAPAB_ENROLLEE) ||
1654 		   (!auth->configurator && role != DPP_CAPAB_CONFIGURATOR)) {
1655 		wpa_printf(MSG_DEBUG, "DPP: Incompatible role selection");
1656 		wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1657 			"Unexpected role in R-capabilities 0x%02x",
1658 			role);
1659 		if (role != DPP_CAPAB_ENROLLEE &&
1660 		    role != DPP_CAPAB_CONFIGURATOR)
1661 			goto fail;
1662 		bin_clear_free(unwrapped, unwrapped_len);
1663 		auth->remove_on_tx_status = 1;
1664 		return dpp_auth_build_conf(auth, DPP_STATUS_NOT_COMPATIBLE);
1665 	}
1666 
1667 	wrapped2 = dpp_get_attr(unwrapped, unwrapped_len,
1668 				DPP_ATTR_WRAPPED_DATA, &wrapped2_len);
1669 	if (!wrapped2 || wrapped2_len < AES_BLOCK_SIZE) {
1670 		dpp_auth_fail(auth,
1671 			      "Missing or invalid Secondary Wrapped Data");
1672 		goto fail;
1673 	}
1674 
1675 	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
1676 		    wrapped2, wrapped2_len);
1677 
1678 	if (dpp_derive_bk_ke(auth) < 0)
1679 		goto fail;
1680 
1681 	unwrapped2_len = wrapped2_len - AES_BLOCK_SIZE;
1682 	unwrapped2 = os_malloc(unwrapped2_len);
1683 	if (!unwrapped2)
1684 		goto fail;
1685 	if (aes_siv_decrypt(auth->ke, auth->curve->hash_len,
1686 			    wrapped2, wrapped2_len,
1687 			    0, NULL, NULL, unwrapped2) < 0) {
1688 		dpp_auth_fail(auth, "AES-SIV decryption failed");
1689 		goto fail;
1690 	}
1691 	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
1692 		    unwrapped2, unwrapped2_len);
1693 
1694 	if (dpp_check_attrs(unwrapped2, unwrapped2_len) < 0) {
1695 		dpp_auth_fail(auth,
1696 			      "Invalid attribute in secondary unwrapped data");
1697 		goto fail;
1698 	}
1699 
1700 	r_auth = dpp_get_attr(unwrapped2, unwrapped2_len, DPP_ATTR_R_AUTH_TAG,
1701 			       &r_auth_len);
1702 	if (!r_auth || r_auth_len != auth->curve->hash_len) {
1703 		dpp_auth_fail(auth,
1704 			      "Missing or invalid Responder Authenticating Tag");
1705 		goto fail;
1706 	}
1707 	wpa_hexdump(MSG_DEBUG, "DPP: Received Responder Authenticating Tag",
1708 		    r_auth, r_auth_len);
1709 	/* R-auth' = H(I-nonce | R-nonce | PI.x | PR.x | [BI.x |] BR.x | 0) */
1710 	if (dpp_gen_r_auth(auth, r_auth2) < 0)
1711 		goto fail;
1712 	wpa_hexdump(MSG_DEBUG, "DPP: Calculated Responder Authenticating Tag",
1713 		    r_auth2, r_auth_len);
1714 	if (os_memcmp(r_auth, r_auth2, r_auth_len) != 0) {
1715 		dpp_auth_fail(auth, "Mismatching Responder Authenticating Tag");
1716 		bin_clear_free(unwrapped, unwrapped_len);
1717 		bin_clear_free(unwrapped2, unwrapped2_len);
1718 		auth->remove_on_tx_status = 1;
1719 		return dpp_auth_build_conf(auth, DPP_STATUS_AUTH_FAILURE);
1720 	}
1721 
1722 	bin_clear_free(unwrapped, unwrapped_len);
1723 	bin_clear_free(unwrapped2, unwrapped2_len);
1724 
1725 #ifdef CONFIG_TESTING_OPTIONS
1726 	if (dpp_test == DPP_TEST_AUTH_RESP_IN_PLACE_OF_CONF) {
1727 		wpa_printf(MSG_INFO,
1728 			   "DPP: TESTING - Authentication Response in place of Confirm");
1729 		if (dpp_auth_build_resp_ok(auth) < 0)
1730 			return NULL;
1731 		return wpabuf_dup(auth->resp_msg);
1732 	}
1733 #endif /* CONFIG_TESTING_OPTIONS */
1734 
1735 	return dpp_auth_build_conf(auth, DPP_STATUS_OK);
1736 
1737 fail:
1738 	bin_clear_free(unwrapped, unwrapped_len);
1739 	bin_clear_free(unwrapped2, unwrapped2_len);
1740 	EVP_PKEY_free(pr);
1741 	return NULL;
1742 }
1743 
1744 
dpp_auth_conf_rx_failure(struct dpp_authentication * auth,const u8 * hdr,const u8 * attr_start,size_t attr_len,const u8 * wrapped_data,u16 wrapped_data_len,enum dpp_status_error status)1745 static int dpp_auth_conf_rx_failure(struct dpp_authentication *auth,
1746 				    const u8 *hdr,
1747 				    const u8 *attr_start, size_t attr_len,
1748 				    const u8 *wrapped_data,
1749 				    u16 wrapped_data_len,
1750 				    enum dpp_status_error status)
1751 {
1752 	const u8 *addr[2];
1753 	size_t len[2];
1754 	u8 *unwrapped = NULL;
1755 	size_t unwrapped_len = 0;
1756 	const u8 *r_nonce;
1757 	u16 r_nonce_len;
1758 
1759 	/* Authentication Confirm failure cases are expected to include
1760 	 * {R-nonce}k2 in the Wrapped Data attribute. */
1761 
1762 	addr[0] = hdr;
1763 	len[0] = DPP_HDR_LEN;
1764 	addr[1] = attr_start;
1765 	len[1] = attr_len;
1766 	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
1767 	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
1768 	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
1769 		    wrapped_data, wrapped_data_len);
1770 	unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
1771 	unwrapped = os_malloc(unwrapped_len);
1772 	if (!unwrapped) {
1773 		dpp_auth_fail(auth, "Authentication failed");
1774 		goto fail;
1775 	}
1776 	if (aes_siv_decrypt(auth->k2, auth->curve->hash_len,
1777 			    wrapped_data, wrapped_data_len,
1778 			    2, addr, len, unwrapped) < 0) {
1779 		dpp_auth_fail(auth, "AES-SIV decryption failed");
1780 		goto fail;
1781 	}
1782 	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
1783 		    unwrapped, unwrapped_len);
1784 
1785 	if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
1786 		dpp_auth_fail(auth, "Invalid attribute in unwrapped data");
1787 		goto fail;
1788 	}
1789 
1790 	r_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_R_NONCE,
1791 			       &r_nonce_len);
1792 	if (!r_nonce || r_nonce_len != auth->curve->nonce_len) {
1793 		dpp_auth_fail(auth, "DPP: Missing or invalid R-nonce");
1794 		goto fail;
1795 	}
1796 	if (os_memcmp(r_nonce, auth->r_nonce, r_nonce_len) != 0) {
1797 		wpa_hexdump(MSG_DEBUG, "DPP: Received R-nonce",
1798 			    r_nonce, r_nonce_len);
1799 		wpa_hexdump(MSG_DEBUG, "DPP: Expected R-nonce",
1800 			    auth->r_nonce, r_nonce_len);
1801 		dpp_auth_fail(auth, "R-nonce mismatch");
1802 		goto fail;
1803 	}
1804 
1805 	if (status == DPP_STATUS_NOT_COMPATIBLE)
1806 		dpp_auth_fail(auth, "Peer reported incompatible R-capab role");
1807 	else if (status == DPP_STATUS_AUTH_FAILURE)
1808 		dpp_auth_fail(auth, "Peer reported authentication failure)");
1809 
1810 fail:
1811 	bin_clear_free(unwrapped, unwrapped_len);
1812 	return -1;
1813 }
1814 
1815 
dpp_auth_conf_rx(struct dpp_authentication * auth,const u8 * hdr,const u8 * attr_start,size_t attr_len)1816 int dpp_auth_conf_rx(struct dpp_authentication *auth, const u8 *hdr,
1817 		     const u8 *attr_start, size_t attr_len)
1818 {
1819 	const u8 *r_bootstrap, *i_bootstrap, *wrapped_data, *status, *i_auth;
1820 	u16 r_bootstrap_len, i_bootstrap_len, wrapped_data_len, status_len,
1821 		i_auth_len;
1822 	const u8 *addr[2];
1823 	size_t len[2];
1824 	u8 *unwrapped = NULL;
1825 	size_t unwrapped_len = 0;
1826 	u8 i_auth2[DPP_MAX_HASH_LEN];
1827 
1828 #ifdef CONFIG_TESTING_OPTIONS
1829 	if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) {
1830 		wpa_printf(MSG_INFO,
1831 			   "DPP: TESTING - stop at Authentication Confirm");
1832 		return -1;
1833 	}
1834 #endif /* CONFIG_TESTING_OPTIONS */
1835 
1836 	if (auth->initiator || !auth->own_bi || !auth->waiting_auth_conf ||
1837 	    auth->reconfig) {
1838 		wpa_printf(MSG_DEBUG,
1839 			   "DPP: initiator=%d own_bi=%d waiting_auth_conf=%d",
1840 			   auth->initiator, !!auth->own_bi,
1841 			   auth->waiting_auth_conf);
1842 		dpp_auth_fail(auth, "Unexpected Authentication Confirm");
1843 		return -1;
1844 	}
1845 
1846 	auth->waiting_auth_conf = 0;
1847 
1848 	wrapped_data = dpp_get_attr(attr_start, attr_len, DPP_ATTR_WRAPPED_DATA,
1849 				    &wrapped_data_len);
1850 	if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) {
1851 		dpp_auth_fail(auth,
1852 			      "Missing or invalid required Wrapped Data attribute");
1853 		return -1;
1854 	}
1855 	wpa_hexdump(MSG_DEBUG, "DPP: Wrapped data",
1856 		    wrapped_data, wrapped_data_len);
1857 
1858 	attr_len = wrapped_data - 4 - attr_start;
1859 
1860 	r_bootstrap = dpp_get_attr(attr_start, attr_len,
1861 				   DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
1862 				   &r_bootstrap_len);
1863 	if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
1864 		dpp_auth_fail(auth,
1865 			      "Missing or invalid required Responder Bootstrapping Key Hash attribute");
1866 		return -1;
1867 	}
1868 	wpa_hexdump(MSG_DEBUG, "DPP: Responder Bootstrapping Key Hash",
1869 		    r_bootstrap, r_bootstrap_len);
1870 	if (os_memcmp(r_bootstrap, auth->own_bi->pubkey_hash,
1871 		      SHA256_MAC_LEN) != 0) {
1872 		wpa_hexdump(MSG_DEBUG,
1873 			    "DPP: Expected Responder Bootstrapping Key Hash",
1874 			    auth->peer_bi->pubkey_hash, SHA256_MAC_LEN);
1875 		dpp_auth_fail(auth,
1876 			      "Responder Bootstrapping Key Hash mismatch");
1877 		return -1;
1878 	}
1879 
1880 	i_bootstrap = dpp_get_attr(attr_start, attr_len,
1881 				   DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
1882 				   &i_bootstrap_len);
1883 	if (i_bootstrap) {
1884 		if (i_bootstrap_len != SHA256_MAC_LEN) {
1885 			dpp_auth_fail(auth,
1886 				      "Invalid Initiator Bootstrapping Key Hash attribute");
1887 			return -1;
1888 		}
1889 		wpa_hexdump(MSG_MSGDUMP,
1890 			    "DPP: Initiator Bootstrapping Key Hash",
1891 			    i_bootstrap, i_bootstrap_len);
1892 		if (!auth->peer_bi ||
1893 		    os_memcmp(i_bootstrap, auth->peer_bi->pubkey_hash,
1894 			      SHA256_MAC_LEN) != 0) {
1895 			dpp_auth_fail(auth,
1896 				      "Initiator Bootstrapping Key Hash mismatch");
1897 			return -1;
1898 		}
1899 	} else if (auth->peer_bi) {
1900 		/* Mutual authentication and peer did not include its
1901 		 * Bootstrapping Key Hash attribute. */
1902 		dpp_auth_fail(auth,
1903 			      "Missing Initiator Bootstrapping Key Hash attribute");
1904 		return -1;
1905 	}
1906 
1907 	status = dpp_get_attr(attr_start, attr_len, DPP_ATTR_STATUS,
1908 			      &status_len);
1909 	if (!status || status_len < 1) {
1910 		dpp_auth_fail(auth,
1911 			      "Missing or invalid required DPP Status attribute");
1912 		return -1;
1913 	}
1914 	wpa_printf(MSG_DEBUG, "DPP: Status %u", status[0]);
1915 	if (status[0] == DPP_STATUS_NOT_COMPATIBLE ||
1916 	    status[0] == DPP_STATUS_AUTH_FAILURE)
1917 		return dpp_auth_conf_rx_failure(auth, hdr, attr_start,
1918 						attr_len, wrapped_data,
1919 						wrapped_data_len, status[0]);
1920 
1921 	if (status[0] != DPP_STATUS_OK) {
1922 		dpp_auth_fail(auth, "Authentication failed");
1923 		return -1;
1924 	}
1925 
1926 	addr[0] = hdr;
1927 	len[0] = DPP_HDR_LEN;
1928 	addr[1] = attr_start;
1929 	len[1] = attr_len;
1930 	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
1931 	wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
1932 	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
1933 		    wrapped_data, wrapped_data_len);
1934 	unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
1935 	unwrapped = os_malloc(unwrapped_len);
1936 	if (!unwrapped)
1937 		return -1;
1938 	if (aes_siv_decrypt(auth->ke, auth->curve->hash_len,
1939 			    wrapped_data, wrapped_data_len,
1940 			    2, addr, len, unwrapped) < 0) {
1941 		dpp_auth_fail(auth, "AES-SIV decryption failed");
1942 		goto fail;
1943 	}
1944 	wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
1945 		    unwrapped, unwrapped_len);
1946 
1947 	if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
1948 		dpp_auth_fail(auth, "Invalid attribute in unwrapped data");
1949 		goto fail;
1950 	}
1951 
1952 	i_auth = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_AUTH_TAG,
1953 			      &i_auth_len);
1954 	if (!i_auth || i_auth_len != auth->curve->hash_len) {
1955 		dpp_auth_fail(auth,
1956 			      "Missing or invalid Initiator Authenticating Tag");
1957 		goto fail;
1958 	}
1959 	wpa_hexdump(MSG_DEBUG, "DPP: Received Initiator Authenticating Tag",
1960 		    i_auth, i_auth_len);
1961 	/* I-auth' = H(R-nonce | I-nonce | PR.x | PI.x | BR.x | [BI.x |] 1) */
1962 	if (dpp_gen_i_auth(auth, i_auth2) < 0)
1963 		goto fail;
1964 	wpa_hexdump(MSG_DEBUG, "DPP: Calculated Initiator Authenticating Tag",
1965 		    i_auth2, i_auth_len);
1966 	if (os_memcmp(i_auth, i_auth2, i_auth_len) != 0) {
1967 		dpp_auth_fail(auth, "Mismatching Initiator Authenticating Tag");
1968 		goto fail;
1969 	}
1970 
1971 	bin_clear_free(unwrapped, unwrapped_len);
1972 	dpp_auth_success(auth);
1973 	return 0;
1974 fail:
1975 	bin_clear_free(unwrapped, unwrapped_len);
1976 	return -1;
1977 }
1978