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