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