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_tries = 0;
255
256 /* Build DPP Authentication Response frame attributes */
257 attr_len = 4 + 1 + 2 * (4 + SHA256_MAC_LEN) +
258 4 + (pr ? wpabuf_len(pr) : 0) + 4 + sizeof(wrapped_data);
259 #ifdef CONFIG_DPP2
260 attr_len += 5;
261 #endif /* CONFIG_DPP2 */
262 #ifdef CONFIG_TESTING_OPTIONS
263 if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_RESP)
264 attr_len += 5;
265 #endif /* CONFIG_TESTING_OPTIONS */
266 msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_RESP, attr_len);
267 if (!msg)
268 return NULL;
269
270 attr_start = wpabuf_put(msg, 0);
271
272 /* DPP Status */
273 if (status != 255)
274 dpp_build_attr_status(msg, status);
275
276 /* Responder Bootstrapping Key Hash */
277 dpp_build_attr_r_bootstrap_key_hash(msg, r_pubkey_hash);
278
279 /* Initiator Bootstrapping Key Hash (mutual authentication) */
280 dpp_build_attr_i_bootstrap_key_hash(msg, i_pubkey_hash);
281
282 /* Responder Protocol Key */
283 if (pr) {
284 wpabuf_put_le16(msg, DPP_ATTR_R_PROTOCOL_KEY);
285 wpabuf_put_le16(msg, wpabuf_len(pr));
286 wpabuf_put_buf(msg, pr);
287 }
288
289 #ifdef CONFIG_DPP2
290 /* Protocol Version */
291 if (auth->peer_version >= 2) {
292 wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
293 wpabuf_put_le16(msg, 1);
294 wpabuf_put_u8(msg, DPP_VERSION);
295 }
296 #endif /* CONFIG_DPP2 */
297
298 attr_end = wpabuf_put(msg, 0);
299
300 #ifdef CONFIG_TESTING_OPTIONS
301 if (dpp_test == DPP_TEST_NO_WRAPPED_DATA_AUTH_RESP) {
302 wpa_printf(MSG_INFO, "DPP: TESTING - no Wrapped Data");
303 goto skip_wrapped_data;
304 }
305 #endif /* CONFIG_TESTING_OPTIONS */
306
307 /* Wrapped data ({R-nonce, I-nonce, R-capabilities, {R-auth}ke}k2) */
308 pos = clear;
309
310 if (r_nonce) {
311 /* R-nonce */
312 WPA_PUT_LE16(pos, DPP_ATTR_R_NONCE);
313 pos += 2;
314 WPA_PUT_LE16(pos, nonce_len);
315 pos += 2;
316 os_memcpy(pos, r_nonce, nonce_len);
317 pos += nonce_len;
318 }
319
320 if (i_nonce) {
321 /* I-nonce */
322 WPA_PUT_LE16(pos, DPP_ATTR_I_NONCE);
323 pos += 2;
324 WPA_PUT_LE16(pos, nonce_len);
325 pos += 2;
326 os_memcpy(pos, i_nonce, nonce_len);
327 #ifdef CONFIG_TESTING_OPTIONS
328 if (dpp_test == DPP_TEST_I_NONCE_MISMATCH_AUTH_RESP) {
329 wpa_printf(MSG_INFO, "DPP: TESTING - I-nonce mismatch");
330 pos[nonce_len / 2] ^= 0x01;
331 }
332 #endif /* CONFIG_TESTING_OPTIONS */
333 pos += nonce_len;
334 }
335
336 #ifdef CONFIG_TESTING_OPTIONS
337 if (dpp_test == DPP_TEST_NO_R_CAPAB_AUTH_RESP) {
338 wpa_printf(MSG_INFO, "DPP: TESTING - no R-capab");
339 goto skip_r_capab;
340 }
341 #endif /* CONFIG_TESTING_OPTIONS */
342
343 /* R-capabilities */
344 WPA_PUT_LE16(pos, DPP_ATTR_R_CAPABILITIES);
345 pos += 2;
346 WPA_PUT_LE16(pos, 1);
347 pos += 2;
348 auth->r_capab = auth->configurator ? DPP_CAPAB_CONFIGURATOR :
349 DPP_CAPAB_ENROLLEE;
350 *pos++ = auth->r_capab;
351 #ifdef CONFIG_TESTING_OPTIONS
352 if (dpp_test == DPP_TEST_ZERO_R_CAPAB) {
353 wpa_printf(MSG_INFO, "DPP: TESTING - zero R-capabilities");
354 pos[-1] = 0;
355 } else if (dpp_test == DPP_TEST_INCOMPATIBLE_R_CAPAB_AUTH_RESP) {
356 wpa_printf(MSG_INFO,
357 "DPP: TESTING - incompatible R-capabilities");
358 if ((auth->i_capab & DPP_CAPAB_ROLE_MASK) ==
359 (DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE))
360 pos[-1] = 0;
361 else
362 pos[-1] = auth->configurator ? DPP_CAPAB_ENROLLEE :
363 DPP_CAPAB_CONFIGURATOR;
364 }
365 skip_r_capab:
366 #endif /* CONFIG_TESTING_OPTIONS */
367
368 if (wrapped_r_auth) {
369 /* {R-auth}ke */
370 WPA_PUT_LE16(pos, DPP_ATTR_WRAPPED_DATA);
371 pos += 2;
372 WPA_PUT_LE16(pos, wrapped_r_auth_len);
373 pos += 2;
374 os_memcpy(pos, wrapped_r_auth, wrapped_r_auth_len);
375 pos += wrapped_r_auth_len;
376 }
377
378 /* OUI, OUI type, Crypto Suite, DPP frame type */
379 addr[0] = wpabuf_head_u8(msg) + 2;
380 len[0] = 3 + 1 + 1 + 1;
381 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
382
383 /* Attributes before Wrapped Data */
384 addr[1] = attr_start;
385 len[1] = attr_end - attr_start;
386 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
387
388 siv_len = pos - clear;
389 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", clear, siv_len);
390 if (aes_siv_encrypt(siv_key, auth->curve->hash_len, clear, siv_len,
391 2, addr, len, wrapped_data) < 0) {
392 wpabuf_free(msg);
393 return NULL;
394 }
395 siv_len += AES_BLOCK_SIZE;
396 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
397 wrapped_data, siv_len);
398
399 wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
400 wpabuf_put_le16(msg, siv_len);
401 wpabuf_put_data(msg, wrapped_data, siv_len);
402
403 #ifdef CONFIG_TESTING_OPTIONS
404 if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_RESP) {
405 wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
406 dpp_build_attr_status(msg, DPP_STATUS_OK);
407 }
408 skip_wrapped_data:
409 #endif /* CONFIG_TESTING_OPTIONS */
410
411 wpa_hexdump_buf(MSG_DEBUG,
412 "DPP: Authentication Response frame attributes", msg);
413 return msg;
414 }
415
416
dpp_auth_build_resp_ok(struct dpp_authentication * auth)417 static int dpp_auth_build_resp_ok(struct dpp_authentication *auth)
418 {
419 size_t nonce_len;
420 size_t secret_len;
421 struct wpabuf *msg, *pr = NULL;
422 u8 r_auth[4 + DPP_MAX_HASH_LEN];
423 u8 wrapped_r_auth[4 + DPP_MAX_HASH_LEN + AES_BLOCK_SIZE], *w_r_auth;
424 size_t wrapped_r_auth_len;
425 int ret = -1;
426 const u8 *r_pubkey_hash, *i_pubkey_hash, *r_nonce, *i_nonce;
427 enum dpp_status_error status = DPP_STATUS_OK;
428 #ifdef CONFIG_TESTING_OPTIONS
429 u8 test_hash[SHA256_MAC_LEN];
430 #endif /* CONFIG_TESTING_OPTIONS */
431
432 wpa_printf(MSG_DEBUG, "DPP: Build Authentication Response");
433 if (!auth->own_bi)
434 return -1;
435
436 #ifdef CONFIG_TESTING_OPTIONS
437 if (dpp_nonce_override_len > 0) {
438 wpa_printf(MSG_INFO, "DPP: TESTING - override R-nonce");
439 nonce_len = dpp_nonce_override_len;
440 os_memcpy(auth->r_nonce, dpp_nonce_override, nonce_len);
441 } else {
442 nonce_len = auth->curve->nonce_len;
443 if (random_get_bytes(auth->r_nonce, nonce_len)) {
444 wpa_printf(MSG_ERROR,
445 "DPP: Failed to generate R-nonce");
446 goto fail;
447 }
448 }
449 #else /* CONFIG_TESTING_OPTIONS */
450 nonce_len = auth->curve->nonce_len;
451 if (random_get_bytes(auth->r_nonce, nonce_len)) {
452 wpa_printf(MSG_ERROR, "DPP: Failed to generate R-nonce");
453 goto fail;
454 }
455 #endif /* CONFIG_TESTING_OPTIONS */
456 wpa_hexdump(MSG_DEBUG, "DPP: R-nonce", auth->r_nonce, nonce_len);
457
458 EVP_PKEY_free(auth->own_protocol_key);
459 #ifdef CONFIG_TESTING_OPTIONS
460 if (dpp_protocol_key_override_len) {
461 const struct dpp_curve_params *tmp_curve;
462
463 wpa_printf(MSG_INFO,
464 "DPP: TESTING - override protocol key");
465 auth->own_protocol_key = dpp_set_keypair(
466 &tmp_curve, dpp_protocol_key_override,
467 dpp_protocol_key_override_len);
468 } else {
469 auth->own_protocol_key = dpp_gen_keypair(auth->curve);
470 }
471 #else /* CONFIG_TESTING_OPTIONS */
472 auth->own_protocol_key = dpp_gen_keypair(auth->curve);
473 #endif /* CONFIG_TESTING_OPTIONS */
474 if (!auth->own_protocol_key)
475 goto fail;
476
477 pr = dpp_get_pubkey_point(auth->own_protocol_key, 0);
478 if (!pr)
479 goto fail;
480
481 /* ECDH: N = pR * PI */
482 if (dpp_ecdh(auth->own_protocol_key, auth->peer_protocol_key,
483 auth->Nx, &secret_len) < 0)
484 goto fail;
485
486 wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (N.x)",
487 auth->Nx, auth->secret_len);
488 auth->Nx_len = auth->secret_len;
489
490 if (dpp_derive_k2(auth->Nx, auth->secret_len, auth->k2,
491 auth->curve->hash_len) < 0)
492 goto fail;
493
494 if (auth->own_bi && auth->peer_bi) {
495 /* Mutual authentication */
496 if (dpp_auth_derive_l_responder(auth) < 0)
497 goto fail;
498 }
499
500 if (dpp_derive_bk_ke(auth) < 0)
501 goto fail;
502
503 /* R-auth = H(I-nonce | R-nonce | PI.x | PR.x | [BI.x |] BR.x | 0) */
504 WPA_PUT_LE16(r_auth, DPP_ATTR_R_AUTH_TAG);
505 WPA_PUT_LE16(&r_auth[2], auth->curve->hash_len);
506 if (dpp_gen_r_auth(auth, r_auth + 4) < 0)
507 goto fail;
508 #ifdef CONFIG_TESTING_OPTIONS
509 if (dpp_test == DPP_TEST_R_AUTH_MISMATCH_AUTH_RESP) {
510 wpa_printf(MSG_INFO, "DPP: TESTING - R-auth mismatch");
511 r_auth[4 + auth->curve->hash_len / 2] ^= 0x01;
512 }
513 #endif /* CONFIG_TESTING_OPTIONS */
514 if (aes_siv_encrypt(auth->ke, auth->curve->hash_len,
515 r_auth, 4 + auth->curve->hash_len,
516 0, NULL, NULL, wrapped_r_auth) < 0)
517 goto fail;
518 wrapped_r_auth_len = 4 + auth->curve->hash_len + AES_BLOCK_SIZE;
519 wpa_hexdump(MSG_DEBUG, "DPP: {R-auth}ke",
520 wrapped_r_auth, wrapped_r_auth_len);
521 w_r_auth = wrapped_r_auth;
522
523 r_pubkey_hash = auth->own_bi->pubkey_hash;
524 if (auth->peer_bi)
525 i_pubkey_hash = auth->peer_bi->pubkey_hash;
526 else
527 i_pubkey_hash = NULL;
528
529 i_nonce = auth->i_nonce;
530 r_nonce = auth->r_nonce;
531
532 #ifdef CONFIG_TESTING_OPTIONS
533 if (dpp_test == DPP_TEST_NO_R_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
534 wpa_printf(MSG_INFO, "DPP: TESTING - no R-Bootstrap Key Hash");
535 r_pubkey_hash = NULL;
536 } else if (dpp_test ==
537 DPP_TEST_INVALID_R_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
538 wpa_printf(MSG_INFO,
539 "DPP: TESTING - invalid R-Bootstrap Key Hash");
540 os_memcpy(test_hash, r_pubkey_hash, SHA256_MAC_LEN);
541 test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
542 r_pubkey_hash = test_hash;
543 } else if (dpp_test == DPP_TEST_NO_I_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
544 wpa_printf(MSG_INFO, "DPP: TESTING - no I-Bootstrap Key Hash");
545 i_pubkey_hash = NULL;
546 } else if (dpp_test ==
547 DPP_TEST_INVALID_I_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
548 wpa_printf(MSG_INFO,
549 "DPP: TESTING - invalid I-Bootstrap Key Hash");
550 if (i_pubkey_hash)
551 os_memcpy(test_hash, i_pubkey_hash, SHA256_MAC_LEN);
552 else
553 os_memset(test_hash, 0, SHA256_MAC_LEN);
554 test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
555 i_pubkey_hash = test_hash;
556 } else if (dpp_test == DPP_TEST_NO_R_PROTO_KEY_AUTH_RESP) {
557 wpa_printf(MSG_INFO, "DPP: TESTING - no R-Proto Key");
558 wpabuf_free(pr);
559 pr = NULL;
560 } else if (dpp_test == DPP_TEST_INVALID_R_PROTO_KEY_AUTH_RESP) {
561 wpa_printf(MSG_INFO, "DPP: TESTING - invalid R-Proto Key");
562 wpabuf_free(pr);
563 pr = wpabuf_alloc(2 * auth->curve->prime_len);
564 if (!pr || dpp_test_gen_invalid_key(pr, auth->curve) < 0)
565 goto fail;
566 } else if (dpp_test == DPP_TEST_NO_R_AUTH_AUTH_RESP) {
567 wpa_printf(MSG_INFO, "DPP: TESTING - no R-Auth");
568 w_r_auth = NULL;
569 wrapped_r_auth_len = 0;
570 } else if (dpp_test == DPP_TEST_NO_STATUS_AUTH_RESP) {
571 wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
572 status = 255;
573 } else if (dpp_test == DPP_TEST_INVALID_STATUS_AUTH_RESP) {
574 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status");
575 status = 254;
576 } else if (dpp_test == DPP_TEST_NO_R_NONCE_AUTH_RESP) {
577 wpa_printf(MSG_INFO, "DPP: TESTING - no R-nonce");
578 r_nonce = NULL;
579 } else if (dpp_test == DPP_TEST_NO_I_NONCE_AUTH_RESP) {
580 wpa_printf(MSG_INFO, "DPP: TESTING - no I-nonce");
581 i_nonce = NULL;
582 }
583 #endif /* CONFIG_TESTING_OPTIONS */
584
585 msg = dpp_auth_build_resp(auth, status, pr, nonce_len,
586 r_pubkey_hash, i_pubkey_hash,
587 r_nonce, i_nonce,
588 w_r_auth, wrapped_r_auth_len,
589 auth->k2);
590 if (!msg)
591 goto fail;
592 wpabuf_free(auth->resp_msg);
593 auth->resp_msg = msg;
594 ret = 0;
595 fail:
596 wpabuf_free(pr);
597 return ret;
598 }
599
600
dpp_auth_build_resp_status(struct dpp_authentication * auth,enum dpp_status_error status)601 static int dpp_auth_build_resp_status(struct dpp_authentication *auth,
602 enum dpp_status_error status)
603 {
604 struct wpabuf *msg;
605 const u8 *r_pubkey_hash, *i_pubkey_hash, *i_nonce;
606 #ifdef CONFIG_TESTING_OPTIONS
607 u8 test_hash[SHA256_MAC_LEN];
608 #endif /* CONFIG_TESTING_OPTIONS */
609
610 if (!auth->own_bi)
611 return -1;
612 wpa_printf(MSG_DEBUG, "DPP: Build Authentication Response");
613
614 r_pubkey_hash = auth->own_bi->pubkey_hash;
615 if (auth->peer_bi)
616 i_pubkey_hash = auth->peer_bi->pubkey_hash;
617 else
618 i_pubkey_hash = NULL;
619
620 i_nonce = auth->i_nonce;
621
622 #ifdef CONFIG_TESTING_OPTIONS
623 if (dpp_test == DPP_TEST_NO_R_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
624 wpa_printf(MSG_INFO, "DPP: TESTING - no R-Bootstrap Key Hash");
625 r_pubkey_hash = NULL;
626 } else if (dpp_test ==
627 DPP_TEST_INVALID_R_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
628 wpa_printf(MSG_INFO,
629 "DPP: TESTING - invalid R-Bootstrap Key Hash");
630 os_memcpy(test_hash, r_pubkey_hash, SHA256_MAC_LEN);
631 test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
632 r_pubkey_hash = test_hash;
633 } else if (dpp_test == DPP_TEST_NO_I_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
634 wpa_printf(MSG_INFO, "DPP: TESTING - no I-Bootstrap Key Hash");
635 i_pubkey_hash = NULL;
636 } else if (dpp_test ==
637 DPP_TEST_INVALID_I_BOOTSTRAP_KEY_HASH_AUTH_RESP) {
638 wpa_printf(MSG_INFO,
639 "DPP: TESTING - invalid I-Bootstrap Key Hash");
640 if (i_pubkey_hash)
641 os_memcpy(test_hash, i_pubkey_hash, SHA256_MAC_LEN);
642 else
643 os_memset(test_hash, 0, SHA256_MAC_LEN);
644 test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
645 i_pubkey_hash = test_hash;
646 } else if (dpp_test == DPP_TEST_NO_STATUS_AUTH_RESP) {
647 wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
648 status = 255;
649 } else if (dpp_test == DPP_TEST_NO_I_NONCE_AUTH_RESP) {
650 wpa_printf(MSG_INFO, "DPP: TESTING - no I-nonce");
651 i_nonce = NULL;
652 }
653 #endif /* CONFIG_TESTING_OPTIONS */
654
655 msg = dpp_auth_build_resp(auth, status, NULL, auth->curve->nonce_len,
656 r_pubkey_hash, i_pubkey_hash,
657 NULL, i_nonce, NULL, 0, auth->k1);
658 if (!msg)
659 return -1;
660 wpabuf_free(auth->resp_msg);
661 auth->resp_msg = msg;
662 return 0;
663 }
664
665
666 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)667 dpp_auth_req_rx(struct dpp_global *dpp, void *msg_ctx, u8 dpp_allowed_roles,
668 int qr_mutual, struct dpp_bootstrap_info *peer_bi,
669 struct dpp_bootstrap_info *own_bi,
670 unsigned int freq, const u8 *hdr, const u8 *attr_start,
671 size_t attr_len)
672 {
673 EVP_PKEY *pi = NULL;
674 EVP_PKEY_CTX *ctx = 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 EVP_PKEY_free(pi);
931 EVP_PKEY_CTX_free(ctx);
932 dpp_auth_deinit(auth);
933 return NULL;
934 }
935
936
dpp_notify_new_qr_code(struct dpp_authentication * auth,struct dpp_bootstrap_info * peer_bi)937 int dpp_notify_new_qr_code(struct dpp_authentication *auth,
938 struct dpp_bootstrap_info *peer_bi)
939 {
940 if (!auth || !auth->response_pending ||
941 os_memcmp(auth->waiting_pubkey_hash, peer_bi->pubkey_hash,
942 SHA256_MAC_LEN) != 0)
943 return 0;
944
945 wpa_printf(MSG_DEBUG,
946 "DPP: New scanned QR Code has matching public key that was needed to continue DPP Authentication exchange with "
947 MACSTR, MAC2STR(auth->peer_mac_addr));
948 auth->peer_bi = peer_bi;
949
950 if (dpp_auth_build_resp_ok(auth) < 0)
951 return -1;
952
953 return 1;
954 }
955
956
dpp_auth_build_conf(struct dpp_authentication * auth,enum dpp_status_error status)957 static struct wpabuf * dpp_auth_build_conf(struct dpp_authentication *auth,
958 enum dpp_status_error status)
959 {
960 struct wpabuf *msg;
961 u8 i_auth[4 + DPP_MAX_HASH_LEN];
962 size_t i_auth_len;
963 u8 r_nonce[4 + DPP_MAX_NONCE_LEN];
964 size_t r_nonce_len;
965 const u8 *addr[2];
966 size_t len[2], attr_len;
967 u8 *wrapped_i_auth;
968 u8 *wrapped_r_nonce;
969 u8 *attr_start, *attr_end;
970 const u8 *r_pubkey_hash, *i_pubkey_hash;
971 #ifdef CONFIG_TESTING_OPTIONS
972 u8 test_hash[SHA256_MAC_LEN];
973 #endif /* CONFIG_TESTING_OPTIONS */
974
975 wpa_printf(MSG_DEBUG, "DPP: Build Authentication Confirmation");
976
977 i_auth_len = 4 + auth->curve->hash_len;
978 r_nonce_len = 4 + auth->curve->nonce_len;
979 /* Build DPP Authentication Confirmation frame attributes */
980 attr_len = 4 + 1 + 2 * (4 + SHA256_MAC_LEN) +
981 4 + i_auth_len + r_nonce_len + AES_BLOCK_SIZE;
982 #ifdef CONFIG_TESTING_OPTIONS
983 if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_CONF)
984 attr_len += 5;
985 #endif /* CONFIG_TESTING_OPTIONS */
986 msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_CONF, attr_len);
987 if (!msg)
988 goto fail;
989
990 attr_start = wpabuf_put(msg, 0);
991
992 r_pubkey_hash = auth->peer_bi->pubkey_hash;
993 if (auth->own_bi)
994 i_pubkey_hash = auth->own_bi->pubkey_hash;
995 else
996 i_pubkey_hash = NULL;
997
998 #ifdef CONFIG_TESTING_OPTIONS
999 if (dpp_test == DPP_TEST_NO_STATUS_AUTH_CONF) {
1000 wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
1001 goto skip_status;
1002 } else if (dpp_test == DPP_TEST_INVALID_STATUS_AUTH_CONF) {
1003 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status");
1004 status = 254;
1005 }
1006 #endif /* CONFIG_TESTING_OPTIONS */
1007
1008 /* DPP Status */
1009 dpp_build_attr_status(msg, status);
1010
1011 #ifdef CONFIG_TESTING_OPTIONS
1012 skip_status:
1013 if (dpp_test == DPP_TEST_NO_R_BOOTSTRAP_KEY_HASH_AUTH_CONF) {
1014 wpa_printf(MSG_INFO, "DPP: TESTING - no R-Bootstrap Key Hash");
1015 r_pubkey_hash = NULL;
1016 } else if (dpp_test ==
1017 DPP_TEST_INVALID_R_BOOTSTRAP_KEY_HASH_AUTH_CONF) {
1018 wpa_printf(MSG_INFO,
1019 "DPP: TESTING - invalid R-Bootstrap Key Hash");
1020 os_memcpy(test_hash, r_pubkey_hash, SHA256_MAC_LEN);
1021 test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
1022 r_pubkey_hash = test_hash;
1023 } else if (dpp_test == DPP_TEST_NO_I_BOOTSTRAP_KEY_HASH_AUTH_CONF) {
1024 wpa_printf(MSG_INFO, "DPP: TESTING - no I-Bootstrap Key Hash");
1025 i_pubkey_hash = NULL;
1026 } else if (dpp_test ==
1027 DPP_TEST_INVALID_I_BOOTSTRAP_KEY_HASH_AUTH_CONF) {
1028 wpa_printf(MSG_INFO,
1029 "DPP: TESTING - invalid I-Bootstrap Key Hash");
1030 if (i_pubkey_hash)
1031 os_memcpy(test_hash, i_pubkey_hash, SHA256_MAC_LEN);
1032 else
1033 os_memset(test_hash, 0, SHA256_MAC_LEN);
1034 test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
1035 i_pubkey_hash = test_hash;
1036 }
1037 #endif /* CONFIG_TESTING_OPTIONS */
1038
1039 /* Responder Bootstrapping Key Hash */
1040 dpp_build_attr_r_bootstrap_key_hash(msg, r_pubkey_hash);
1041
1042 /* Initiator Bootstrapping Key Hash (mutual authentication) */
1043 dpp_build_attr_i_bootstrap_key_hash(msg, i_pubkey_hash);
1044
1045 #ifdef CONFIG_TESTING_OPTIONS
1046 if (dpp_test == DPP_TEST_NO_WRAPPED_DATA_AUTH_CONF)
1047 goto skip_wrapped_data;
1048 if (dpp_test == DPP_TEST_NO_I_AUTH_AUTH_CONF)
1049 i_auth_len = 0;
1050 #endif /* CONFIG_TESTING_OPTIONS */
1051
1052 attr_end = wpabuf_put(msg, 0);
1053
1054 /* OUI, OUI type, Crypto Suite, DPP frame type */
1055 addr[0] = wpabuf_head_u8(msg) + 2;
1056 len[0] = 3 + 1 + 1 + 1;
1057 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
1058
1059 /* Attributes before Wrapped Data */
1060 addr[1] = attr_start;
1061 len[1] = attr_end - attr_start;
1062 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
1063
1064 if (status == DPP_STATUS_OK) {
1065 /* I-auth wrapped with ke */
1066 wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
1067 wpabuf_put_le16(msg, i_auth_len + AES_BLOCK_SIZE);
1068 wrapped_i_auth = wpabuf_put(msg, i_auth_len + AES_BLOCK_SIZE);
1069
1070 #ifdef CONFIG_TESTING_OPTIONS
1071 if (dpp_test == DPP_TEST_NO_I_AUTH_AUTH_CONF)
1072 goto skip_i_auth;
1073 #endif /* CONFIG_TESTING_OPTIONS */
1074
1075 /* I-auth = H(R-nonce | I-nonce | PR.x | PI.x | BR.x | [BI.x |]
1076 * 1) */
1077 WPA_PUT_LE16(i_auth, DPP_ATTR_I_AUTH_TAG);
1078 WPA_PUT_LE16(&i_auth[2], auth->curve->hash_len);
1079 if (dpp_gen_i_auth(auth, i_auth + 4) < 0)
1080 goto fail;
1081
1082 #ifdef CONFIG_TESTING_OPTIONS
1083 if (dpp_test == DPP_TEST_I_AUTH_MISMATCH_AUTH_CONF) {
1084 wpa_printf(MSG_INFO, "DPP: TESTING - I-auth mismatch");
1085 i_auth[4 + auth->curve->hash_len / 2] ^= 0x01;
1086 }
1087 skip_i_auth:
1088 #endif /* CONFIG_TESTING_OPTIONS */
1089 if (aes_siv_encrypt(auth->ke, auth->curve->hash_len,
1090 i_auth, i_auth_len,
1091 2, addr, len, wrapped_i_auth) < 0)
1092 goto fail;
1093 wpa_hexdump(MSG_DEBUG, "DPP: {I-auth}ke",
1094 wrapped_i_auth, i_auth_len + AES_BLOCK_SIZE);
1095 } else {
1096 /* R-nonce wrapped with k2 */
1097 wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
1098 wpabuf_put_le16(msg, r_nonce_len + AES_BLOCK_SIZE);
1099 wrapped_r_nonce = wpabuf_put(msg, r_nonce_len + AES_BLOCK_SIZE);
1100
1101 WPA_PUT_LE16(r_nonce, DPP_ATTR_R_NONCE);
1102 WPA_PUT_LE16(&r_nonce[2], auth->curve->nonce_len);
1103 os_memcpy(r_nonce + 4, auth->r_nonce, auth->curve->nonce_len);
1104
1105 if (aes_siv_encrypt(auth->k2, auth->curve->hash_len,
1106 r_nonce, r_nonce_len,
1107 2, addr, len, wrapped_r_nonce) < 0)
1108 goto fail;
1109 wpa_hexdump(MSG_DEBUG, "DPP: {R-nonce}k2",
1110 wrapped_r_nonce, r_nonce_len + AES_BLOCK_SIZE);
1111 }
1112
1113 #ifdef CONFIG_TESTING_OPTIONS
1114 if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_CONF) {
1115 wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
1116 dpp_build_attr_status(msg, DPP_STATUS_OK);
1117 }
1118 skip_wrapped_data:
1119 #endif /* CONFIG_TESTING_OPTIONS */
1120
1121 wpa_hexdump_buf(MSG_DEBUG,
1122 "DPP: Authentication Confirmation frame attributes",
1123 msg);
1124 if (status == DPP_STATUS_OK)
1125 dpp_auth_success(auth);
1126
1127 return msg;
1128
1129 fail:
1130 wpabuf_free(msg);
1131 return NULL;
1132 }
1133
1134
dpp_autogen_bootstrap_key(struct dpp_authentication * auth)1135 static int dpp_autogen_bootstrap_key(struct dpp_authentication *auth)
1136 {
1137 struct dpp_bootstrap_info *bi;
1138
1139 if (auth->own_bi)
1140 return 0; /* already generated */
1141
1142 bi = os_zalloc(sizeof(*bi));
1143 if (!bi)
1144 return -1;
1145 bi->type = DPP_BOOTSTRAP_QR_CODE;
1146 if (dpp_keygen(bi, auth->peer_bi->curve->name, NULL, 0) < 0 ||
1147 dpp_gen_uri(bi) < 0)
1148 goto fail;
1149 wpa_printf(MSG_DEBUG,
1150 "DPP: Auto-generated own bootstrapping key info: URI %s",
1151 bi->uri);
1152
1153 auth->tmp_own_bi = auth->own_bi = bi;
1154
1155 return 0;
1156 fail:
1157 dpp_bootstrap_info_free(bi);
1158 return -1;
1159 }
1160
1161
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)1162 struct dpp_authentication * dpp_auth_init(struct dpp_global *dpp, void *msg_ctx,
1163 struct dpp_bootstrap_info *peer_bi,
1164 struct dpp_bootstrap_info *own_bi,
1165 u8 dpp_allowed_roles,
1166 unsigned int neg_freq,
1167 struct hostapd_hw_modes *own_modes,
1168 u16 num_modes)
1169 {
1170 struct dpp_authentication *auth;
1171 size_t nonce_len;
1172 size_t secret_len;
1173 struct wpabuf *pi = NULL;
1174 const u8 *r_pubkey_hash, *i_pubkey_hash;
1175 #ifdef CONFIG_TESTING_OPTIONS
1176 u8 test_hash[SHA256_MAC_LEN];
1177 #endif /* CONFIG_TESTING_OPTIONS */
1178
1179 auth = dpp_alloc_auth(dpp, msg_ctx);
1180 if (!auth)
1181 return NULL;
1182 if (peer_bi->configurator_params &&
1183 dpp_set_configurator(auth, peer_bi->configurator_params) < 0)
1184 goto fail;
1185 auth->initiator = 1;
1186 auth->waiting_auth_resp = 1;
1187 auth->allowed_roles = dpp_allowed_roles;
1188 auth->configurator = !!(dpp_allowed_roles & DPP_CAPAB_CONFIGURATOR);
1189 auth->peer_bi = peer_bi;
1190 auth->own_bi = own_bi;
1191 auth->curve = peer_bi->curve;
1192
1193 if (dpp_autogen_bootstrap_key(auth) < 0 ||
1194 dpp_prepare_channel_list(auth, neg_freq, own_modes, num_modes) < 0)
1195 goto fail;
1196
1197 #ifdef CONFIG_TESTING_OPTIONS
1198 if (dpp_nonce_override_len > 0) {
1199 wpa_printf(MSG_INFO, "DPP: TESTING - override I-nonce");
1200 nonce_len = dpp_nonce_override_len;
1201 os_memcpy(auth->i_nonce, dpp_nonce_override, nonce_len);
1202 } else {
1203 nonce_len = auth->curve->nonce_len;
1204 if (random_get_bytes(auth->i_nonce, nonce_len)) {
1205 wpa_printf(MSG_ERROR,
1206 "DPP: Failed to generate I-nonce");
1207 goto fail;
1208 }
1209 }
1210 #else /* CONFIG_TESTING_OPTIONS */
1211 nonce_len = auth->curve->nonce_len;
1212 if (random_get_bytes(auth->i_nonce, nonce_len)) {
1213 wpa_printf(MSG_ERROR, "DPP: Failed to generate I-nonce");
1214 goto fail;
1215 }
1216 #endif /* CONFIG_TESTING_OPTIONS */
1217 wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", auth->i_nonce, nonce_len);
1218
1219 #ifdef CONFIG_TESTING_OPTIONS
1220 if (dpp_protocol_key_override_len) {
1221 const struct dpp_curve_params *tmp_curve;
1222
1223 wpa_printf(MSG_INFO,
1224 "DPP: TESTING - override protocol key");
1225 auth->own_protocol_key = dpp_set_keypair(
1226 &tmp_curve, dpp_protocol_key_override,
1227 dpp_protocol_key_override_len);
1228 } else {
1229 auth->own_protocol_key = dpp_gen_keypair(auth->curve);
1230 }
1231 #else /* CONFIG_TESTING_OPTIONS */
1232 auth->own_protocol_key = dpp_gen_keypair(auth->curve);
1233 #endif /* CONFIG_TESTING_OPTIONS */
1234 if (!auth->own_protocol_key)
1235 goto fail;
1236
1237 pi = dpp_get_pubkey_point(auth->own_protocol_key, 0);
1238 if (!pi)
1239 goto fail;
1240
1241 /* ECDH: M = pI * BR */
1242 if (dpp_ecdh(auth->own_protocol_key, auth->peer_bi->pubkey,
1243 auth->Mx, &secret_len) < 0)
1244 goto fail;
1245 auth->secret_len = secret_len;
1246
1247 wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (M.x)",
1248 auth->Mx, auth->secret_len);
1249 auth->Mx_len = auth->secret_len;
1250
1251 if (dpp_derive_k1(auth->Mx, auth->secret_len, auth->k1,
1252 auth->curve->hash_len) < 0)
1253 goto fail;
1254
1255 r_pubkey_hash = auth->peer_bi->pubkey_hash;
1256 i_pubkey_hash = auth->own_bi->pubkey_hash;
1257
1258 #ifdef CONFIG_TESTING_OPTIONS
1259 if (dpp_test == DPP_TEST_NO_R_BOOTSTRAP_KEY_HASH_AUTH_REQ) {
1260 wpa_printf(MSG_INFO, "DPP: TESTING - no R-Bootstrap Key Hash");
1261 r_pubkey_hash = NULL;
1262 } else if (dpp_test == DPP_TEST_INVALID_R_BOOTSTRAP_KEY_HASH_AUTH_REQ) {
1263 wpa_printf(MSG_INFO,
1264 "DPP: TESTING - invalid R-Bootstrap Key Hash");
1265 os_memcpy(test_hash, r_pubkey_hash, SHA256_MAC_LEN);
1266 test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
1267 r_pubkey_hash = test_hash;
1268 } else if (dpp_test == DPP_TEST_NO_I_BOOTSTRAP_KEY_HASH_AUTH_REQ) {
1269 wpa_printf(MSG_INFO, "DPP: TESTING - no I-Bootstrap Key Hash");
1270 i_pubkey_hash = NULL;
1271 } else if (dpp_test == DPP_TEST_INVALID_I_BOOTSTRAP_KEY_HASH_AUTH_REQ) {
1272 wpa_printf(MSG_INFO,
1273 "DPP: TESTING - invalid I-Bootstrap Key Hash");
1274 os_memcpy(test_hash, i_pubkey_hash, SHA256_MAC_LEN);
1275 test_hash[SHA256_MAC_LEN - 1] ^= 0x01;
1276 i_pubkey_hash = test_hash;
1277 } else if (dpp_test == DPP_TEST_NO_I_PROTO_KEY_AUTH_REQ) {
1278 wpa_printf(MSG_INFO, "DPP: TESTING - no I-Proto Key");
1279 wpabuf_free(pi);
1280 pi = NULL;
1281 } else if (dpp_test == DPP_TEST_INVALID_I_PROTO_KEY_AUTH_REQ) {
1282 wpa_printf(MSG_INFO, "DPP: TESTING - invalid I-Proto Key");
1283 wpabuf_free(pi);
1284 pi = wpabuf_alloc(2 * auth->curve->prime_len);
1285 if (!pi || dpp_test_gen_invalid_key(pi, auth->curve) < 0)
1286 goto fail;
1287 }
1288 #endif /* CONFIG_TESTING_OPTIONS */
1289
1290 if (neg_freq && auth->num_freq == 1 && auth->freq[0] == neg_freq)
1291 neg_freq = 0;
1292 auth->req_msg = dpp_auth_build_req(auth, pi, nonce_len, r_pubkey_hash,
1293 i_pubkey_hash, neg_freq);
1294 if (!auth->req_msg)
1295 goto fail;
1296
1297 out:
1298 wpabuf_free(pi);
1299 return auth;
1300 fail:
1301 dpp_auth_deinit(auth);
1302 auth = NULL;
1303 goto out;
1304 }
1305 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)1306 dpp_auth_resp_rx_status(struct dpp_authentication *auth, const u8 *hdr,
1307 const u8 *attr_start, size_t attr_len,
1308 const u8 *wrapped_data, u16 wrapped_data_len,
1309 enum dpp_status_error status)
1310 {
1311 const u8 *addr[2];
1312 size_t len[2];
1313 u8 *unwrapped = NULL;
1314 size_t unwrapped_len = 0;
1315 const u8 *i_nonce, *r_capab;
1316 u16 i_nonce_len, r_capab_len;
1317
1318 if (status == DPP_STATUS_NOT_COMPATIBLE) {
1319 wpa_printf(MSG_DEBUG,
1320 "DPP: Responder reported incompatible roles");
1321 } else if (status == DPP_STATUS_RESPONSE_PENDING) {
1322 wpa_printf(MSG_DEBUG,
1323 "DPP: Responder reported more time needed");
1324 } else {
1325 wpa_printf(MSG_DEBUG,
1326 "DPP: Responder reported failure (status %d)",
1327 status);
1328 dpp_auth_fail(auth, "Responder reported failure");
1329 return;
1330 }
1331
1332 addr[0] = hdr;
1333 len[0] = DPP_HDR_LEN;
1334 addr[1] = attr_start;
1335 len[1] = attr_len;
1336 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
1337 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
1338 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
1339 wrapped_data, wrapped_data_len);
1340 unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
1341 unwrapped = os_malloc(unwrapped_len);
1342 if (!unwrapped)
1343 goto fail;
1344 if (aes_siv_decrypt(auth->k1, auth->curve->hash_len,
1345 wrapped_data, wrapped_data_len,
1346 2, addr, len, unwrapped) < 0) {
1347 dpp_auth_fail(auth, "AES-SIV decryption failed");
1348 goto fail;
1349 }
1350 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
1351 unwrapped, unwrapped_len);
1352
1353 if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
1354 dpp_auth_fail(auth, "Invalid attribute in unwrapped data");
1355 goto fail;
1356 }
1357
1358 i_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_NONCE,
1359 &i_nonce_len);
1360 if (!i_nonce || i_nonce_len != auth->curve->nonce_len) {
1361 dpp_auth_fail(auth, "Missing or invalid I-nonce");
1362 goto fail;
1363 }
1364 wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", i_nonce, i_nonce_len);
1365 if (os_memcmp(auth->i_nonce, i_nonce, i_nonce_len) != 0) {
1366 dpp_auth_fail(auth, "I-nonce mismatch");
1367 goto fail;
1368 }
1369
1370 r_capab = dpp_get_attr(unwrapped, unwrapped_len,
1371 DPP_ATTR_R_CAPABILITIES,
1372 &r_capab_len);
1373 if (!r_capab || r_capab_len < 1) {
1374 dpp_auth_fail(auth, "Missing or invalid R-capabilities");
1375 goto fail;
1376 }
1377 auth->r_capab = r_capab[0];
1378 wpa_printf(MSG_DEBUG, "DPP: R-capabilities: 0x%02x", auth->r_capab);
1379 if (status == DPP_STATUS_NOT_COMPATIBLE) {
1380 wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_NOT_COMPATIBLE
1381 "r-capab=0x%02x", auth->r_capab);
1382 } else if (status == DPP_STATUS_RESPONSE_PENDING) {
1383 u8 role = auth->r_capab & DPP_CAPAB_ROLE_MASK;
1384
1385 if ((auth->configurator && role != DPP_CAPAB_ENROLLEE) ||
1386 (!auth->configurator && role != DPP_CAPAB_CONFIGURATOR)) {
1387 wpa_msg(auth->msg_ctx, MSG_INFO,
1388 DPP_EVENT_FAIL "Unexpected role in R-capabilities 0x%02x",
1389 role);
1390 } else {
1391 wpa_printf(MSG_DEBUG,
1392 "DPP: Continue waiting for full DPP Authentication Response");
1393 wpa_msg(auth->msg_ctx, MSG_INFO,
1394 DPP_EVENT_RESPONSE_PENDING "%s",
1395 auth->tmp_own_bi ? auth->tmp_own_bi->uri : "");
1396 }
1397 }
1398 fail:
1399 bin_clear_free(unwrapped, unwrapped_len);
1400 }
1401
1402
1403 struct wpabuf *
dpp_auth_resp_rx(struct dpp_authentication * auth,const u8 * hdr,const u8 * attr_start,size_t attr_len)1404 dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr,
1405 const u8 *attr_start, size_t attr_len)
1406 {
1407 EVP_PKEY *pr;
1408 size_t secret_len;
1409 const u8 *addr[2];
1410 size_t len[2];
1411 u8 *unwrapped = NULL, *unwrapped2 = NULL;
1412 size_t unwrapped_len = 0, unwrapped2_len = 0;
1413 const u8 *r_bootstrap, *i_bootstrap, *wrapped_data, *status, *r_proto,
1414 *r_nonce, *i_nonce, *r_capab, *wrapped2, *r_auth;
1415 u16 r_bootstrap_len, i_bootstrap_len, wrapped_data_len, status_len,
1416 r_proto_len, r_nonce_len, i_nonce_len, r_capab_len,
1417 wrapped2_len, r_auth_len;
1418 u8 r_auth2[DPP_MAX_HASH_LEN];
1419 u8 role;
1420 #ifdef CONFIG_DPP2
1421 const u8 *version;
1422 u16 version_len;
1423 #endif /* CONFIG_DPP2 */
1424
1425 #ifdef CONFIG_TESTING_OPTIONS
1426 if (dpp_test == DPP_TEST_STOP_AT_AUTH_RESP) {
1427 wpa_printf(MSG_INFO,
1428 "DPP: TESTING - stop at Authentication Response");
1429 return NULL;
1430 }
1431 #endif /* CONFIG_TESTING_OPTIONS */
1432
1433 if (!auth->initiator || !auth->peer_bi || auth->reconfig) {
1434 dpp_auth_fail(auth, "Unexpected Authentication Response");
1435 return NULL;
1436 }
1437
1438 auth->waiting_auth_resp = 0;
1439
1440 wrapped_data = dpp_get_attr(attr_start, attr_len, DPP_ATTR_WRAPPED_DATA,
1441 &wrapped_data_len);
1442 if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) {
1443 dpp_auth_fail(auth,
1444 "Missing or invalid required Wrapped Data attribute");
1445 return NULL;
1446 }
1447 wpa_hexdump(MSG_DEBUG, "DPP: Wrapped data",
1448 wrapped_data, wrapped_data_len);
1449
1450 attr_len = wrapped_data - 4 - attr_start;
1451
1452 r_bootstrap = dpp_get_attr(attr_start, attr_len,
1453 DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
1454 &r_bootstrap_len);
1455 if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
1456 dpp_auth_fail(auth,
1457 "Missing or invalid required Responder Bootstrapping Key Hash attribute");
1458 return NULL;
1459 }
1460 wpa_hexdump(MSG_DEBUG, "DPP: Responder Bootstrapping Key Hash",
1461 r_bootstrap, r_bootstrap_len);
1462 if (os_memcmp(r_bootstrap, auth->peer_bi->pubkey_hash,
1463 SHA256_MAC_LEN) != 0) {
1464 dpp_auth_fail(auth,
1465 "Unexpected Responder Bootstrapping Key Hash value");
1466 wpa_hexdump(MSG_DEBUG,
1467 "DPP: Expected Responder Bootstrapping Key Hash",
1468 auth->peer_bi->pubkey_hash, SHA256_MAC_LEN);
1469 return NULL;
1470 }
1471
1472 i_bootstrap = dpp_get_attr(attr_start, attr_len,
1473 DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
1474 &i_bootstrap_len);
1475 if (i_bootstrap) {
1476 if (i_bootstrap_len != SHA256_MAC_LEN) {
1477 dpp_auth_fail(auth,
1478 "Invalid Initiator Bootstrapping Key Hash attribute");
1479 return NULL;
1480 }
1481 wpa_hexdump(MSG_MSGDUMP,
1482 "DPP: Initiator Bootstrapping Key Hash",
1483 i_bootstrap, i_bootstrap_len);
1484 if (!auth->own_bi ||
1485 os_memcmp(i_bootstrap, auth->own_bi->pubkey_hash,
1486 SHA256_MAC_LEN) != 0) {
1487 dpp_auth_fail(auth,
1488 "Initiator Bootstrapping Key Hash attribute did not match");
1489 return NULL;
1490 }
1491 } else if (auth->own_bi && auth->own_bi->type == DPP_BOOTSTRAP_PKEX) {
1492 /* PKEX bootstrapping mandates use of mutual authentication */
1493 dpp_auth_fail(auth,
1494 "Missing Initiator Bootstrapping Key Hash attribute");
1495 return NULL;
1496 } else if (auth->own_bi &&
1497 auth->own_bi->type == DPP_BOOTSTRAP_NFC_URI &&
1498 auth->own_bi->nfc_negotiated) {
1499 /* NFC negotiated connection handover bootstrapping mandates
1500 * use of mutual authentication */
1501 dpp_auth_fail(auth,
1502 "Missing Initiator Bootstrapping Key Hash attribute");
1503 return NULL;
1504 }
1505
1506 auth->peer_version = 1; /* default to the first version */
1507 #ifdef CONFIG_DPP2
1508 version = dpp_get_attr(attr_start, attr_len, DPP_ATTR_PROTOCOL_VERSION,
1509 &version_len);
1510 if (version && DPP_VERSION > 1) {
1511 if (version_len < 1 || version[0] == 0) {
1512 dpp_auth_fail(auth,
1513 "Invalid Protocol Version attribute");
1514 return NULL;
1515 }
1516 auth->peer_version = version[0];
1517 wpa_printf(MSG_DEBUG, "DPP: Peer protocol version %u",
1518 auth->peer_version);
1519 }
1520 #endif /* CONFIG_DPP2 */
1521
1522 status = dpp_get_attr(attr_start, attr_len, DPP_ATTR_STATUS,
1523 &status_len);
1524 if (!status || status_len < 1) {
1525 dpp_auth_fail(auth,
1526 "Missing or invalid required DPP Status attribute");
1527 return NULL;
1528 }
1529 wpa_printf(MSG_DEBUG, "DPP: Status %u", status[0]);
1530 auth->auth_resp_status = status[0];
1531 if (status[0] != DPP_STATUS_OK) {
1532 dpp_auth_resp_rx_status(auth, hdr, attr_start,
1533 attr_len, wrapped_data,
1534 wrapped_data_len, status[0]);
1535 return NULL;
1536 }
1537
1538 if (!i_bootstrap && auth->own_bi) {
1539 wpa_printf(MSG_DEBUG,
1540 "DPP: Responder decided not to use mutual authentication");
1541 auth->own_bi = NULL;
1542 }
1543
1544 wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_DIRECTION "mutual=%d",
1545 auth->own_bi != NULL);
1546
1547 r_proto = dpp_get_attr(attr_start, attr_len, DPP_ATTR_R_PROTOCOL_KEY,
1548 &r_proto_len);
1549 if (!r_proto) {
1550 dpp_auth_fail(auth,
1551 "Missing required Responder Protocol Key attribute");
1552 return NULL;
1553 }
1554 wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Protocol Key",
1555 r_proto, r_proto_len);
1556
1557 /* N = pI * PR */
1558 pr = dpp_set_pubkey_point(auth->own_protocol_key, r_proto, r_proto_len);
1559 if (!pr) {
1560 dpp_auth_fail(auth, "Invalid Responder Protocol Key");
1561 return NULL;
1562 }
1563 dpp_debug_print_key("Peer (Responder) Protocol Key", pr);
1564
1565 if (dpp_ecdh(auth->own_protocol_key, pr, auth->Nx, &secret_len) < 0) {
1566 dpp_auth_fail(auth, "Failed to derive ECDH shared secret");
1567 goto fail;
1568 }
1569 EVP_PKEY_free(auth->peer_protocol_key);
1570 auth->peer_protocol_key = pr;
1571 pr = NULL;
1572
1573 wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (N.x)",
1574 auth->Nx, auth->secret_len);
1575 auth->Nx_len = auth->secret_len;
1576
1577 if (dpp_derive_k2(auth->Nx, auth->secret_len, auth->k2,
1578 auth->curve->hash_len) < 0)
1579 goto fail;
1580
1581 addr[0] = hdr;
1582 len[0] = DPP_HDR_LEN;
1583 addr[1] = attr_start;
1584 len[1] = attr_len;
1585 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
1586 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
1587 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
1588 wrapped_data, wrapped_data_len);
1589 unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
1590 unwrapped = os_malloc(unwrapped_len);
1591 if (!unwrapped)
1592 goto fail;
1593 if (aes_siv_decrypt(auth->k2, auth->curve->hash_len,
1594 wrapped_data, wrapped_data_len,
1595 2, addr, len, unwrapped) < 0) {
1596 dpp_auth_fail(auth, "AES-SIV decryption failed");
1597 goto fail;
1598 }
1599 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
1600 unwrapped, unwrapped_len);
1601
1602 if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
1603 dpp_auth_fail(auth, "Invalid attribute in unwrapped data");
1604 goto fail;
1605 }
1606
1607 r_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_R_NONCE,
1608 &r_nonce_len);
1609 if (!r_nonce || r_nonce_len != auth->curve->nonce_len) {
1610 dpp_auth_fail(auth, "DPP: Missing or invalid R-nonce");
1611 goto fail;
1612 }
1613 wpa_hexdump(MSG_DEBUG, "DPP: R-nonce", r_nonce, r_nonce_len);
1614 os_memcpy(auth->r_nonce, r_nonce, r_nonce_len);
1615
1616 i_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_NONCE,
1617 &i_nonce_len);
1618 if (!i_nonce || i_nonce_len != auth->curve->nonce_len) {
1619 dpp_auth_fail(auth, "Missing or invalid I-nonce");
1620 goto fail;
1621 }
1622 wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", i_nonce, i_nonce_len);
1623 if (os_memcmp(auth->i_nonce, i_nonce, i_nonce_len) != 0) {
1624 dpp_auth_fail(auth, "I-nonce mismatch");
1625 goto fail;
1626 }
1627
1628 if (auth->own_bi) {
1629 /* Mutual authentication */
1630 if (dpp_auth_derive_l_initiator(auth) < 0)
1631 goto fail;
1632 }
1633
1634 r_capab = dpp_get_attr(unwrapped, unwrapped_len,
1635 DPP_ATTR_R_CAPABILITIES,
1636 &r_capab_len);
1637 if (!r_capab || r_capab_len < 1) {
1638 dpp_auth_fail(auth, "Missing or invalid R-capabilities");
1639 goto fail;
1640 }
1641 auth->r_capab = r_capab[0];
1642 wpa_printf(MSG_DEBUG, "DPP: R-capabilities: 0x%02x", auth->r_capab);
1643 role = auth->r_capab & DPP_CAPAB_ROLE_MASK;
1644 if ((auth->allowed_roles ==
1645 (DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE)) &&
1646 (role == DPP_CAPAB_CONFIGURATOR || role == DPP_CAPAB_ENROLLEE)) {
1647 /* Peer selected its role, so move from "either role" to the
1648 * role that is compatible with peer's selection. */
1649 auth->configurator = role == DPP_CAPAB_ENROLLEE;
1650 wpa_printf(MSG_DEBUG, "DPP: Acting as %s",
1651 auth->configurator ? "Configurator" : "Enrollee");
1652 } else if ((auth->configurator && role != DPP_CAPAB_ENROLLEE) ||
1653 (!auth->configurator && role != DPP_CAPAB_CONFIGURATOR)) {
1654 wpa_printf(MSG_DEBUG, "DPP: Incompatible role selection");
1655 wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1656 "Unexpected role in R-capabilities 0x%02x",
1657 role);
1658 if (role != DPP_CAPAB_ENROLLEE &&
1659 role != DPP_CAPAB_CONFIGURATOR)
1660 goto fail;
1661 bin_clear_free(unwrapped, unwrapped_len);
1662 auth->remove_on_tx_status = 1;
1663 return dpp_auth_build_conf(auth, DPP_STATUS_NOT_COMPATIBLE);
1664 }
1665
1666 wrapped2 = dpp_get_attr(unwrapped, unwrapped_len,
1667 DPP_ATTR_WRAPPED_DATA, &wrapped2_len);
1668 if (!wrapped2 || wrapped2_len < AES_BLOCK_SIZE) {
1669 dpp_auth_fail(auth,
1670 "Missing or invalid Secondary Wrapped Data");
1671 goto fail;
1672 }
1673
1674 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
1675 wrapped2, wrapped2_len);
1676
1677 if (dpp_derive_bk_ke(auth) < 0)
1678 goto fail;
1679
1680 unwrapped2_len = wrapped2_len - AES_BLOCK_SIZE;
1681 unwrapped2 = os_malloc(unwrapped2_len);
1682 if (!unwrapped2)
1683 goto fail;
1684 if (aes_siv_decrypt(auth->ke, auth->curve->hash_len,
1685 wrapped2, wrapped2_len,
1686 0, NULL, NULL, unwrapped2) < 0) {
1687 dpp_auth_fail(auth, "AES-SIV decryption failed");
1688 goto fail;
1689 }
1690 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
1691 unwrapped2, unwrapped2_len);
1692
1693 if (dpp_check_attrs(unwrapped2, unwrapped2_len) < 0) {
1694 dpp_auth_fail(auth,
1695 "Invalid attribute in secondary unwrapped data");
1696 goto fail;
1697 }
1698
1699 r_auth = dpp_get_attr(unwrapped2, unwrapped2_len, DPP_ATTR_R_AUTH_TAG,
1700 &r_auth_len);
1701 if (!r_auth || r_auth_len != auth->curve->hash_len) {
1702 dpp_auth_fail(auth,
1703 "Missing or invalid Responder Authenticating Tag");
1704 goto fail;
1705 }
1706 wpa_hexdump(MSG_DEBUG, "DPP: Received Responder Authenticating Tag",
1707 r_auth, r_auth_len);
1708 /* R-auth' = H(I-nonce | R-nonce | PI.x | PR.x | [BI.x |] BR.x | 0) */
1709 if (dpp_gen_r_auth(auth, r_auth2) < 0)
1710 goto fail;
1711 wpa_hexdump(MSG_DEBUG, "DPP: Calculated Responder Authenticating Tag",
1712 r_auth2, r_auth_len);
1713 if (os_memcmp(r_auth, r_auth2, r_auth_len) != 0) {
1714 dpp_auth_fail(auth, "Mismatching Responder Authenticating Tag");
1715 bin_clear_free(unwrapped, unwrapped_len);
1716 bin_clear_free(unwrapped2, unwrapped2_len);
1717 auth->remove_on_tx_status = 1;
1718 return dpp_auth_build_conf(auth, DPP_STATUS_AUTH_FAILURE);
1719 }
1720
1721 bin_clear_free(unwrapped, unwrapped_len);
1722 bin_clear_free(unwrapped2, unwrapped2_len);
1723
1724 #ifdef CONFIG_TESTING_OPTIONS
1725 if (dpp_test == DPP_TEST_AUTH_RESP_IN_PLACE_OF_CONF) {
1726 wpa_printf(MSG_INFO,
1727 "DPP: TESTING - Authentication Response in place of Confirm");
1728 if (dpp_auth_build_resp_ok(auth) < 0)
1729 return NULL;
1730 return wpabuf_dup(auth->resp_msg);
1731 }
1732 #endif /* CONFIG_TESTING_OPTIONS */
1733
1734 return dpp_auth_build_conf(auth, DPP_STATUS_OK);
1735
1736 fail:
1737 bin_clear_free(unwrapped, unwrapped_len);
1738 bin_clear_free(unwrapped2, unwrapped2_len);
1739 EVP_PKEY_free(pr);
1740 return NULL;
1741 }
1742
1743
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)1744 static int dpp_auth_conf_rx_failure(struct dpp_authentication *auth,
1745 const u8 *hdr,
1746 const u8 *attr_start, size_t attr_len,
1747 const u8 *wrapped_data,
1748 u16 wrapped_data_len,
1749 enum dpp_status_error status)
1750 {
1751 const u8 *addr[2];
1752 size_t len[2];
1753 u8 *unwrapped = NULL;
1754 size_t unwrapped_len = 0;
1755 const u8 *r_nonce;
1756 u16 r_nonce_len;
1757
1758 /* Authentication Confirm failure cases are expected to include
1759 * {R-nonce}k2 in the Wrapped Data attribute. */
1760
1761 addr[0] = hdr;
1762 len[0] = DPP_HDR_LEN;
1763 addr[1] = attr_start;
1764 len[1] = attr_len;
1765 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
1766 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
1767 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
1768 wrapped_data, wrapped_data_len);
1769 unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
1770 unwrapped = os_malloc(unwrapped_len);
1771 if (!unwrapped) {
1772 dpp_auth_fail(auth, "Authentication failed");
1773 goto fail;
1774 }
1775 if (aes_siv_decrypt(auth->k2, auth->curve->hash_len,
1776 wrapped_data, wrapped_data_len,
1777 2, addr, len, unwrapped) < 0) {
1778 dpp_auth_fail(auth, "AES-SIV decryption failed");
1779 goto fail;
1780 }
1781 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
1782 unwrapped, unwrapped_len);
1783
1784 if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
1785 dpp_auth_fail(auth, "Invalid attribute in unwrapped data");
1786 goto fail;
1787 }
1788
1789 r_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_R_NONCE,
1790 &r_nonce_len);
1791 if (!r_nonce || r_nonce_len != auth->curve->nonce_len) {
1792 dpp_auth_fail(auth, "DPP: Missing or invalid R-nonce");
1793 goto fail;
1794 }
1795 if (os_memcmp(r_nonce, auth->r_nonce, r_nonce_len) != 0) {
1796 wpa_hexdump(MSG_DEBUG, "DPP: Received R-nonce",
1797 r_nonce, r_nonce_len);
1798 wpa_hexdump(MSG_DEBUG, "DPP: Expected R-nonce",
1799 auth->r_nonce, r_nonce_len);
1800 dpp_auth_fail(auth, "R-nonce mismatch");
1801 goto fail;
1802 }
1803
1804 if (status == DPP_STATUS_NOT_COMPATIBLE)
1805 dpp_auth_fail(auth, "Peer reported incompatible R-capab role");
1806 else if (status == DPP_STATUS_AUTH_FAILURE)
1807 dpp_auth_fail(auth, "Peer reported authentication failure)");
1808
1809 fail:
1810 bin_clear_free(unwrapped, unwrapped_len);
1811 return -1;
1812 }
1813
1814
dpp_auth_conf_rx(struct dpp_authentication * auth,const u8 * hdr,const u8 * attr_start,size_t attr_len)1815 int dpp_auth_conf_rx(struct dpp_authentication *auth, const u8 *hdr,
1816 const u8 *attr_start, size_t attr_len)
1817 {
1818 const u8 *r_bootstrap, *i_bootstrap, *wrapped_data, *status, *i_auth;
1819 u16 r_bootstrap_len, i_bootstrap_len, wrapped_data_len, status_len,
1820 i_auth_len;
1821 const u8 *addr[2];
1822 size_t len[2];
1823 u8 *unwrapped = NULL;
1824 size_t unwrapped_len = 0;
1825 u8 i_auth2[DPP_MAX_HASH_LEN];
1826
1827 #ifdef CONFIG_TESTING_OPTIONS
1828 if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) {
1829 wpa_printf(MSG_INFO,
1830 "DPP: TESTING - stop at Authentication Confirm");
1831 return -1;
1832 }
1833 #endif /* CONFIG_TESTING_OPTIONS */
1834
1835 if (auth->initiator || !auth->own_bi || !auth->waiting_auth_conf ||
1836 auth->reconfig) {
1837 wpa_printf(MSG_DEBUG,
1838 "DPP: initiator=%d own_bi=%d waiting_auth_conf=%d",
1839 auth->initiator, !!auth->own_bi,
1840 auth->waiting_auth_conf);
1841 dpp_auth_fail(auth, "Unexpected Authentication Confirm");
1842 return -1;
1843 }
1844
1845 auth->waiting_auth_conf = 0;
1846
1847 wrapped_data = dpp_get_attr(attr_start, attr_len, DPP_ATTR_WRAPPED_DATA,
1848 &wrapped_data_len);
1849 if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) {
1850 dpp_auth_fail(auth,
1851 "Missing or invalid required Wrapped Data attribute");
1852 return -1;
1853 }
1854 wpa_hexdump(MSG_DEBUG, "DPP: Wrapped data",
1855 wrapped_data, wrapped_data_len);
1856
1857 attr_len = wrapped_data - 4 - attr_start;
1858
1859 r_bootstrap = dpp_get_attr(attr_start, attr_len,
1860 DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
1861 &r_bootstrap_len);
1862 if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
1863 dpp_auth_fail(auth,
1864 "Missing or invalid required Responder Bootstrapping Key Hash attribute");
1865 return -1;
1866 }
1867 wpa_hexdump(MSG_DEBUG, "DPP: Responder Bootstrapping Key Hash",
1868 r_bootstrap, r_bootstrap_len);
1869 if (os_memcmp(r_bootstrap, auth->own_bi->pubkey_hash,
1870 SHA256_MAC_LEN) != 0) {
1871 wpa_hexdump(MSG_DEBUG,
1872 "DPP: Expected Responder Bootstrapping Key Hash",
1873 auth->peer_bi->pubkey_hash, SHA256_MAC_LEN);
1874 dpp_auth_fail(auth,
1875 "Responder Bootstrapping Key Hash mismatch");
1876 return -1;
1877 }
1878
1879 i_bootstrap = dpp_get_attr(attr_start, attr_len,
1880 DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
1881 &i_bootstrap_len);
1882 if (i_bootstrap) {
1883 if (i_bootstrap_len != SHA256_MAC_LEN) {
1884 dpp_auth_fail(auth,
1885 "Invalid Initiator Bootstrapping Key Hash attribute");
1886 return -1;
1887 }
1888 wpa_hexdump(MSG_MSGDUMP,
1889 "DPP: Initiator Bootstrapping Key Hash",
1890 i_bootstrap, i_bootstrap_len);
1891 if (!auth->peer_bi ||
1892 os_memcmp(i_bootstrap, auth->peer_bi->pubkey_hash,
1893 SHA256_MAC_LEN) != 0) {
1894 dpp_auth_fail(auth,
1895 "Initiator Bootstrapping Key Hash mismatch");
1896 return -1;
1897 }
1898 } else if (auth->peer_bi) {
1899 /* Mutual authentication and peer did not include its
1900 * Bootstrapping Key Hash attribute. */
1901 dpp_auth_fail(auth,
1902 "Missing Initiator Bootstrapping Key Hash attribute");
1903 return -1;
1904 }
1905
1906 status = dpp_get_attr(attr_start, attr_len, DPP_ATTR_STATUS,
1907 &status_len);
1908 if (!status || status_len < 1) {
1909 dpp_auth_fail(auth,
1910 "Missing or invalid required DPP Status attribute");
1911 return -1;
1912 }
1913 wpa_printf(MSG_DEBUG, "DPP: Status %u", status[0]);
1914 if (status[0] == DPP_STATUS_NOT_COMPATIBLE ||
1915 status[0] == DPP_STATUS_AUTH_FAILURE)
1916 return dpp_auth_conf_rx_failure(auth, hdr, attr_start,
1917 attr_len, wrapped_data,
1918 wrapped_data_len, status[0]);
1919
1920 if (status[0] != DPP_STATUS_OK) {
1921 dpp_auth_fail(auth, "Authentication failed");
1922 return -1;
1923 }
1924
1925 addr[0] = hdr;
1926 len[0] = DPP_HDR_LEN;
1927 addr[1] = attr_start;
1928 len[1] = attr_len;
1929 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
1930 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
1931 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
1932 wrapped_data, wrapped_data_len);
1933 unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
1934 unwrapped = os_malloc(unwrapped_len);
1935 if (!unwrapped)
1936 return -1;
1937 if (aes_siv_decrypt(auth->ke, auth->curve->hash_len,
1938 wrapped_data, wrapped_data_len,
1939 2, addr, len, unwrapped) < 0) {
1940 dpp_auth_fail(auth, "AES-SIV decryption failed");
1941 goto fail;
1942 }
1943 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
1944 unwrapped, unwrapped_len);
1945
1946 if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
1947 dpp_auth_fail(auth, "Invalid attribute in unwrapped data");
1948 goto fail;
1949 }
1950
1951 i_auth = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_AUTH_TAG,
1952 &i_auth_len);
1953 if (!i_auth || i_auth_len != auth->curve->hash_len) {
1954 dpp_auth_fail(auth,
1955 "Missing or invalid Initiator Authenticating Tag");
1956 goto fail;
1957 }
1958 wpa_hexdump(MSG_DEBUG, "DPP: Received Initiator Authenticating Tag",
1959 i_auth, i_auth_len);
1960 /* I-auth' = H(R-nonce | I-nonce | PR.x | PI.x | BR.x | [BI.x |] 1) */
1961 if (dpp_gen_i_auth(auth, i_auth2) < 0)
1962 goto fail;
1963 wpa_hexdump(MSG_DEBUG, "DPP: Calculated Initiator Authenticating Tag",
1964 i_auth2, i_auth_len);
1965 if (os_memcmp(i_auth, i_auth2, i_auth_len) != 0) {
1966 dpp_auth_fail(auth, "Mismatching Initiator Authenticating Tag");
1967 goto fail;
1968 }
1969
1970 bin_clear_free(unwrapped, unwrapped_len);
1971 dpp_auth_success(auth);
1972 return 0;
1973 fail:
1974 bin_clear_free(unwrapped, unwrapped_len);
1975 return -1;
1976 }
1977