xref: /freebsd/contrib/wpa/src/common/dpp_auth.c (revision 4b72b91a7132df1f77bbae194e1071ac621f1edb)
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 	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;
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 	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 
914 not_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;
928 fail:
929 	bin_clear_free(unwrapped, unwrapped_len);
930 	crypto_ec_key_deinit(pi);
931 	dpp_auth_deinit(auth);
932 	return NULL;
933 }
934 
935 
dpp_notify_new_qr_code(struct dpp_authentication * auth,struct dpp_bootstrap_info * peer_bi)936 int 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 
dpp_auth_build_conf(struct dpp_authentication * auth,enum dpp_status_error status)956 static 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
1011 skip_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 		}
1086 skip_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 	}
1117 skip_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 
1128 fail:
1129 	wpabuf_free(msg);
1130 	return NULL;
1131 }
1132 
1133 
dpp_autogen_bootstrap_key(struct dpp_authentication * auth)1134 static 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;
1155 fail:
1156 	dpp_bootstrap_info_free(bi);
1157 	return -1;
1158 }
1159 
1160 
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)1161 struct 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 
1296 out:
1297 	wpabuf_free(pi);
1298 	return auth;
1299 fail:
1300 	dpp_auth_deinit(auth);
1301 	auth = NULL;
1302 	goto out;
1303 }
1304 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)1305 dpp_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 	}
1397 fail:
1398 	bin_clear_free(unwrapped, unwrapped_len);
1399 }
1400 
1401 
1402 struct wpabuf *
dpp_auth_resp_rx(struct dpp_authentication * auth,const u8 * hdr,const u8 * attr_start,size_t attr_len)1403 dpp_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 
1735 fail:
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 
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)1743 static 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 
1808 fail:
1809 	bin_clear_free(unwrapped, unwrapped_len);
1810 	return -1;
1811 }
1812 
1813 
dpp_auth_conf_rx(struct dpp_authentication * auth,const u8 * hdr,const u8 * attr_start,size_t attr_len)1814 int 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;
1972 fail:
1973 	bin_clear_free(unwrapped, unwrapped_len);
1974 	return -1;
1975 }
1976