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