xref: /freebsd/contrib/wpa/src/common/dpp_crypto.c (revision ec0ea6efa1ad229d75c394c1a9b9cac33af2b1d3)
1 /*
2  * DPP crypto functionality
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 "utils/base64.h"
14 #include "utils/json.h"
15 #include "common/ieee802_11_defs.h"
16 #include "crypto/crypto.h"
17 #include "crypto/random.h"
18 #include "crypto/sha384.h"
19 #include "crypto/sha512.h"
20 #include "tls/asn1.h"
21 #include "dpp.h"
22 #include "dpp_i.h"
23 
24 
25 static const struct dpp_curve_params dpp_curves[] = {
26 	/* The mandatory to support and the default NIST P-256 curve needs to
27 	 * be the first entry on this list. */
28 	{ "prime256v1", 32, 32, 16, 32, "P-256", 19, "ES256" },
29 	{ "secp384r1", 48, 48, 24, 48, "P-384", 20, "ES384" },
30 	{ "secp521r1", 64, 64, 32, 66, "P-521", 21, "ES512" },
31 	{ "brainpoolP256r1", 32, 32, 16, 32, "BP-256", 28, "BS256" },
32 	{ "brainpoolP384r1", 48, 48, 24, 48, "BP-384", 29, "BS384" },
33 	{ "brainpoolP512r1", 64, 64, 32, 64, "BP-512", 30, "BS512" },
34 	{ NULL, 0, 0, 0, 0, NULL, 0, NULL }
35 };
36 
37 
38 const struct dpp_curve_params * dpp_get_curve_name(const char *name)
39 {
40 	int i;
41 
42 	if (!name)
43 		return &dpp_curves[0];
44 
45 	for (i = 0; dpp_curves[i].name; i++) {
46 		if (os_strcmp(name, dpp_curves[i].name) == 0 ||
47 		    (dpp_curves[i].jwk_crv &&
48 		     os_strcmp(name, dpp_curves[i].jwk_crv) == 0))
49 			return &dpp_curves[i];
50 	}
51 	return NULL;
52 }
53 
54 
55 const struct dpp_curve_params * dpp_get_curve_jwk_crv(const char *name)
56 {
57 	int i;
58 
59 	for (i = 0; dpp_curves[i].name; i++) {
60 		if (dpp_curves[i].jwk_crv &&
61 		    os_strcmp(name, dpp_curves[i].jwk_crv) == 0)
62 			return &dpp_curves[i];
63 	}
64 	return NULL;
65 }
66 
67 
68 const struct dpp_curve_params * dpp_get_curve_ike_group(u16 group)
69 {
70 	int i;
71 
72 	for (i = 0; dpp_curves[i].name; i++) {
73 		if (dpp_curves[i].ike_group == group)
74 			return &dpp_curves[i];
75 	}
76 	return NULL;
77 }
78 
79 
80 void dpp_debug_print_key(const char *title, struct crypto_ec_key *key)
81 {
82 	struct wpabuf *der = NULL;
83 
84 	crypto_ec_key_debug_print(key, title);
85 
86 	der = crypto_ec_key_get_ecprivate_key(key, true);
87 	if (der) {
88 		wpa_hexdump_buf_key(MSG_DEBUG, "DPP: ECPrivateKey", der);
89 	} else {
90 		der = crypto_ec_key_get_subject_public_key(key);
91 		if (der)
92 			wpa_hexdump_buf_key(MSG_DEBUG, "DPP: EC_PUBKEY", der);
93 	}
94 
95 	wpabuf_clear_free(der);
96 }
97 
98 
99 static int dpp_hash_vector(const struct dpp_curve_params *curve,
100 			   size_t num_elem, const u8 *addr[], const size_t *len,
101 			   u8 *mac)
102 {
103 	if (curve->hash_len == 32)
104 		return sha256_vector(num_elem, addr, len, mac);
105 	if (curve->hash_len == 48)
106 		return sha384_vector(num_elem, addr, len, mac);
107 	if (curve->hash_len == 64)
108 		return sha512_vector(num_elem, addr, len, mac);
109 	return -1;
110 }
111 
112 
113 int dpp_hkdf_expand(size_t hash_len, const u8 *secret, size_t secret_len,
114 		    const char *label, u8 *out, size_t outlen)
115 {
116 	if (hash_len == 32)
117 		return hmac_sha256_kdf(secret, secret_len, NULL,
118 				       (const u8 *) label, os_strlen(label),
119 				       out, outlen);
120 	if (hash_len == 48)
121 		return hmac_sha384_kdf(secret, secret_len, NULL,
122 				       (const u8 *) label, os_strlen(label),
123 				       out, outlen);
124 	if (hash_len == 64)
125 		return hmac_sha512_kdf(secret, secret_len, NULL,
126 				       (const u8 *) label, os_strlen(label),
127 				       out, outlen);
128 	return -1;
129 }
130 
131 
132 int dpp_hmac_vector(size_t hash_len, const u8 *key, size_t key_len,
133 		    size_t num_elem, const u8 *addr[], const size_t *len,
134 		    u8 *mac)
135 {
136 	if (hash_len == 32)
137 		return hmac_sha256_vector(key, key_len, num_elem, addr, len,
138 					  mac);
139 	if (hash_len == 48)
140 		return hmac_sha384_vector(key, key_len, num_elem, addr, len,
141 					  mac);
142 	if (hash_len == 64)
143 		return hmac_sha512_vector(key, key_len, num_elem, addr, len,
144 					  mac);
145 	return -1;
146 }
147 
148 
149 static int dpp_hmac(size_t hash_len, const u8 *key, size_t key_len,
150 		    const u8 *data, size_t data_len, u8 *mac)
151 {
152 	if (hash_len == 32)
153 		return hmac_sha256(key, key_len, data, data_len, mac);
154 	if (hash_len == 48)
155 		return hmac_sha384(key, key_len, data, data_len, mac);
156 	if (hash_len == 64)
157 		return hmac_sha512(key, key_len, data, data_len, mac);
158 	return -1;
159 }
160 
161 
162 #ifdef CONFIG_DPP2
163 
164 static int dpp_pbkdf2_f(size_t hash_len,
165 			const u8 *password, size_t password_len,
166 			const u8 *salt, size_t salt_len,
167 			unsigned int iterations, unsigned int count, u8 *digest)
168 {
169 	unsigned char tmp[DPP_MAX_HASH_LEN], tmp2[DPP_MAX_HASH_LEN];
170 	unsigned int i;
171 	size_t j;
172 	u8 count_buf[4];
173 	const u8 *addr[2];
174 	size_t len[2];
175 
176 	addr[0] = salt;
177 	len[0] = salt_len;
178 	addr[1] = count_buf;
179 	len[1] = 4;
180 
181 	/* F(P, S, c, i) = U1 xor U2 xor ... Uc
182 	 * U1 = PRF(P, S || i)
183 	 * U2 = PRF(P, U1)
184 	 * Uc = PRF(P, Uc-1)
185 	 */
186 
187 	WPA_PUT_BE32(count_buf, count);
188 	if (dpp_hmac_vector(hash_len, password, password_len, 2, addr, len,
189 			    tmp))
190 		return -1;
191 	os_memcpy(digest, tmp, hash_len);
192 
193 	for (i = 1; i < iterations; i++) {
194 		if (dpp_hmac(hash_len, password, password_len, tmp, hash_len,
195 			     tmp2))
196 			return -1;
197 		os_memcpy(tmp, tmp2, hash_len);
198 		for (j = 0; j < hash_len; j++)
199 			digest[j] ^= tmp2[j];
200 	}
201 
202 	return 0;
203 }
204 
205 
206 int dpp_pbkdf2(size_t hash_len, const u8 *password, size_t password_len,
207 	       const u8 *salt, size_t salt_len, unsigned int iterations,
208 	       u8 *buf, size_t buflen)
209 {
210 	unsigned int count = 0;
211 	unsigned char *pos = buf;
212 	size_t left = buflen, plen;
213 	unsigned char digest[DPP_MAX_HASH_LEN];
214 
215 	while (left > 0) {
216 		count++;
217 		if (dpp_pbkdf2_f(hash_len, password, password_len,
218 				 salt, salt_len, iterations, count, digest))
219 			return -1;
220 		plen = left > hash_len ? hash_len : left;
221 		os_memcpy(pos, digest, plen);
222 		pos += plen;
223 		left -= plen;
224 	}
225 
226 	return 0;
227 }
228 
229 #endif /* CONFIG_DPP2 */
230 
231 
232 struct crypto_ec_key * dpp_set_pubkey_point(struct crypto_ec_key *group_key,
233 					    const u8 *buf, size_t len)
234 {
235 	int ike_group = crypto_ec_key_group(group_key);
236 
237 	if (len & 1)
238 		return NULL;
239 
240 	if (ike_group < 0) {
241 		wpa_printf(MSG_ERROR, "DPP: Could not get EC group");
242 		return NULL;
243 	}
244 
245 	return crypto_ec_key_set_pub(ike_group, buf, buf + len / 2, len / 2);
246 }
247 
248 
249 struct crypto_ec_key * dpp_gen_keypair(const struct dpp_curve_params *curve)
250 {
251 	struct crypto_ec_key *key;
252 
253 	wpa_printf(MSG_DEBUG, "DPP: Generating a keypair");
254 
255 	key = crypto_ec_key_gen(curve->ike_group);
256 	if (key && wpa_debug_show_keys)
257 	    dpp_debug_print_key("Own generated key", key);
258 
259 	return key;
260 }
261 
262 
263 struct crypto_ec_key * dpp_set_keypair(const struct dpp_curve_params **curve,
264 				       const u8 *privkey, size_t privkey_len)
265 {
266 	struct crypto_ec_key *key;
267 	int group;
268 
269 	key = crypto_ec_key_parse_priv(privkey, privkey_len);
270 	if (!key) {
271 		wpa_printf(MSG_INFO, "DPP: Failed to parse private key");
272 		return NULL;
273 	}
274 
275 	group = crypto_ec_key_group(key);
276 	if (group < 0) {
277 		crypto_ec_key_deinit(key);
278 		return NULL;
279 	}
280 
281 	*curve = dpp_get_curve_ike_group(group);
282 	if (!*curve) {
283 		wpa_printf(MSG_INFO,
284 			   "DPP: Unsupported curve (group=%d) in pre-assigned key",
285 			   group);
286 		crypto_ec_key_deinit(key);
287 		return NULL;
288 	}
289 
290 	return key;
291 }
292 
293 
294 int dpp_bootstrap_key_hash(struct dpp_bootstrap_info *bi)
295 {
296 	struct wpabuf *der;
297 	int res;
298 
299 	der = crypto_ec_key_get_subject_public_key(bi->pubkey);
300 	if (!der)
301 		return -1;
302 	wpa_hexdump_buf(MSG_DEBUG, "DPP: Compressed public key (DER)",
303 			der);
304 	res = dpp_bi_pubkey_hash(bi, wpabuf_head(der), wpabuf_len(der));
305 	if (res < 0)
306 		wpa_printf(MSG_DEBUG, "DPP: Failed to hash public key");
307 	wpabuf_free(der);
308 	return res;
309 }
310 
311 
312 int dpp_keygen(struct dpp_bootstrap_info *bi, const char *curve,
313 	       const u8 *privkey, size_t privkey_len)
314 {
315 	char *base64 = NULL;
316 	char *pos, *end;
317 	size_t len;
318 	struct wpabuf *der = NULL;
319 
320 	bi->curve = dpp_get_curve_name(curve);
321 	if (!bi->curve) {
322 		wpa_printf(MSG_INFO, "DPP: Unsupported curve: %s", curve);
323 		return -1;
324 	}
325 
326 	if (privkey)
327 		bi->pubkey = dpp_set_keypair(&bi->curve, privkey, privkey_len);
328 	else
329 		bi->pubkey = dpp_gen_keypair(bi->curve);
330 	if (!bi->pubkey)
331 		goto fail;
332 	bi->own = 1;
333 
334 	der = crypto_ec_key_get_subject_public_key(bi->pubkey);
335 	if (!der)
336 		goto fail;
337 	wpa_hexdump_buf(MSG_DEBUG, "DPP: Compressed public key (DER)",
338 			der);
339 
340 	if (dpp_bi_pubkey_hash(bi, wpabuf_head(der), wpabuf_len(der)) < 0) {
341 		wpa_printf(MSG_DEBUG, "DPP: Failed to hash public key");
342 		goto fail;
343 	}
344 
345 	base64 = base64_encode(wpabuf_head(der), wpabuf_len(der), &len);
346 	wpabuf_free(der);
347 	der = NULL;
348 	if (!base64)
349 		goto fail;
350 	pos = base64;
351 	end = pos + len;
352 	for (;;) {
353 		pos = os_strchr(pos, '\n');
354 		if (!pos)
355 			break;
356 		os_memmove(pos, pos + 1, end - pos);
357 	}
358 	os_free(bi->pk);
359 	bi->pk = base64;
360 	return 0;
361 fail:
362 	os_free(base64);
363 	wpabuf_free(der);
364 	return -1;
365 }
366 
367 
368 int dpp_derive_k1(const u8 *Mx, size_t Mx_len, u8 *k1, unsigned int hash_len)
369 {
370 	u8 salt[DPP_MAX_HASH_LEN], prk[DPP_MAX_HASH_LEN];
371 	const char *info = "first intermediate key";
372 	int res;
373 
374 	/* k1 = HKDF(<>, "first intermediate key", M.x) */
375 
376 	/* HKDF-Extract(<>, M.x) */
377 	os_memset(salt, 0, hash_len);
378 	if (dpp_hmac(hash_len, salt, hash_len, Mx, Mx_len, prk) < 0)
379 		return -1;
380 	wpa_hexdump_key(MSG_DEBUG, "DPP: PRK = HKDF-Extract(<>, IKM=M.x)",
381 			prk, hash_len);
382 
383 	/* HKDF-Expand(PRK, info, L) */
384 	res = dpp_hkdf_expand(hash_len, prk, hash_len, info, k1, hash_len);
385 	os_memset(prk, 0, hash_len);
386 	if (res < 0)
387 		return -1;
388 
389 	wpa_hexdump_key(MSG_DEBUG, "DPP: k1 = HKDF-Expand(PRK, info, L)",
390 			k1, hash_len);
391 	return 0;
392 }
393 
394 
395 int dpp_derive_k2(const u8 *Nx, size_t Nx_len, u8 *k2, unsigned int hash_len)
396 {
397 	u8 salt[DPP_MAX_HASH_LEN], prk[DPP_MAX_HASH_LEN];
398 	const char *info = "second intermediate key";
399 	int res;
400 
401 	/* k2 = HKDF(<>, "second intermediate key", N.x) */
402 
403 	/* HKDF-Extract(<>, N.x) */
404 	os_memset(salt, 0, hash_len);
405 	res = dpp_hmac(hash_len, salt, hash_len, Nx, Nx_len, prk);
406 	if (res < 0)
407 		return -1;
408 	wpa_hexdump_key(MSG_DEBUG, "DPP: PRK = HKDF-Extract(<>, IKM=N.x)",
409 			prk, hash_len);
410 
411 	/* HKDF-Expand(PRK, info, L) */
412 	res = dpp_hkdf_expand(hash_len, prk, hash_len, info, k2, hash_len);
413 	os_memset(prk, 0, hash_len);
414 	if (res < 0)
415 		return -1;
416 
417 	wpa_hexdump_key(MSG_DEBUG, "DPP: k2 = HKDF-Expand(PRK, info, L)",
418 			k2, hash_len);
419 	return 0;
420 }
421 
422 
423 int dpp_derive_bk_ke(struct dpp_authentication *auth)
424 {
425 	unsigned int hash_len = auth->curve->hash_len;
426 	size_t nonce_len = auth->curve->nonce_len;
427 	u8 nonces[2 * DPP_MAX_NONCE_LEN];
428 	const char *info_ke = "DPP Key";
429 	int res;
430 	const u8 *addr[3];
431 	size_t len[3];
432 	size_t num_elem = 0;
433 
434 	if (!auth->Mx_len || !auth->Nx_len) {
435 		wpa_printf(MSG_DEBUG,
436 			   "DPP: Mx/Nx not available - cannot derive ke");
437 		return -1;
438 	}
439 
440 	/* bk = HKDF-Extract(I-nonce | R-nonce, M.x | N.x [| L.x]) */
441 	os_memcpy(nonces, auth->i_nonce, nonce_len);
442 	os_memcpy(&nonces[nonce_len], auth->r_nonce, nonce_len);
443 	addr[num_elem] = auth->Mx;
444 	len[num_elem] = auth->Mx_len;
445 	num_elem++;
446 	addr[num_elem] = auth->Nx;
447 	len[num_elem] = auth->Nx_len;
448 	num_elem++;
449 	if (auth->peer_bi && auth->own_bi) {
450 		if (!auth->Lx_len) {
451 			wpa_printf(MSG_DEBUG,
452 				   "DPP: Lx not available - cannot derive ke");
453 			return -1;
454 		}
455 		addr[num_elem] = auth->Lx;
456 		len[num_elem] = auth->secret_len;
457 		num_elem++;
458 	}
459 	res = dpp_hmac_vector(hash_len, nonces, 2 * nonce_len,
460 			      num_elem, addr, len, auth->bk);
461 	if (res < 0)
462 		return -1;
463 	wpa_hexdump_key(MSG_DEBUG,
464 			"DPP: bk = HKDF-Extract(I-nonce | R-nonce, M.x | N.x [| L.x])",
465 			auth->bk, hash_len);
466 
467 	/* ke = HKDF-Expand(bk, "DPP Key", length) */
468 	res = dpp_hkdf_expand(hash_len, auth->bk, hash_len, info_ke, auth->ke,
469 			      hash_len);
470 	if (res < 0)
471 		return -1;
472 
473 	wpa_hexdump_key(MSG_DEBUG,
474 			"DPP: ke = HKDF-Expand(bk, \"DPP Key\", length)",
475 			auth->ke, hash_len);
476 
477 	return 0;
478 }
479 
480 
481 int dpp_ecdh(struct crypto_ec_key *own, struct crypto_ec_key *peer,
482 	     u8 *secret, size_t *secret_len)
483 {
484 	struct crypto_ecdh *ecdh;
485 	struct wpabuf *peer_pub, *secret_buf = NULL;
486 	int ret = -1;
487 
488 	*secret_len = 0;
489 
490 	ecdh = crypto_ecdh_init2(crypto_ec_key_group(own), own);
491 	if (!ecdh) {
492 		wpa_printf(MSG_ERROR, "DPP: crypto_ecdh_init2() failed");
493 		return -1;
494 	}
495 
496 	peer_pub = crypto_ec_key_get_pubkey_point(peer, 0);
497 	if (!peer_pub) {
498 		wpa_printf(MSG_ERROR,
499 			   "DPP: crypto_ec_key_get_pubkey_point() failed");
500 		goto fail;
501 	}
502 
503 	secret_buf = crypto_ecdh_set_peerkey(ecdh, 1, wpabuf_head(peer_pub),
504 					     wpabuf_len(peer_pub));
505 	if (!secret_buf) {
506 		wpa_printf(MSG_ERROR, "DPP: crypto_ecdh_set_peerkey() failed");
507 		goto fail;
508 	}
509 
510 	if (wpabuf_len(secret_buf) > DPP_MAX_SHARED_SECRET_LEN) {
511 		wpa_printf(MSG_ERROR, "DPP: ECDH secret longer than expected");
512 		goto fail;
513 	}
514 
515 	*secret_len = wpabuf_len(secret_buf);
516 	os_memcpy(secret, wpabuf_head(secret_buf), wpabuf_len(secret_buf));
517 	ret = 0;
518 
519 fail:
520 	wpabuf_clear_free(secret_buf);
521 	wpabuf_free(peer_pub);
522 	crypto_ecdh_deinit(ecdh);
523 	return ret;
524 }
525 
526 
527 int dpp_bi_pubkey_hash(struct dpp_bootstrap_info *bi,
528 		       const u8 *data, size_t data_len)
529 {
530 	const u8 *addr[2];
531 	size_t len[2];
532 
533 	addr[0] = data;
534 	len[0] = data_len;
535 	if (sha256_vector(1, addr, len, bi->pubkey_hash) < 0)
536 		return -1;
537 	wpa_hexdump(MSG_DEBUG, "DPP: Public key hash",
538 		    bi->pubkey_hash, SHA256_MAC_LEN);
539 
540 	addr[0] = (const u8 *) "chirp";
541 	len[0] = 5;
542 	addr[1] = data;
543 	len[1] = data_len;
544 	if (sha256_vector(2, addr, len, bi->pubkey_hash_chirp) < 0)
545 		return -1;
546 	wpa_hexdump(MSG_DEBUG, "DPP: Public key hash (chirp)",
547 		    bi->pubkey_hash_chirp, SHA256_MAC_LEN);
548 
549 	return 0;
550 }
551 
552 
553 int dpp_get_subject_public_key(struct dpp_bootstrap_info *bi,
554 			       const u8 *data, size_t data_len)
555 {
556 	struct crypto_ec_key *key;
557 
558 	if (dpp_bi_pubkey_hash(bi, data, data_len) < 0) {
559 		wpa_printf(MSG_DEBUG, "DPP: Failed to hash public key");
560 		return -1;
561 	}
562 
563 	key = crypto_ec_key_parse_pub(data, data_len);
564 	if (!key) {
565 		wpa_printf(MSG_DEBUG,
566 			   "DPP: Could not parse URI public-key SubjectPublicKeyInfo");
567 		return -1;
568 	}
569 
570 	bi->curve = dpp_get_curve_ike_group(crypto_ec_key_group(key));
571 	if (!bi->curve) {
572 		wpa_printf(MSG_DEBUG,
573 			   "DPP: Unsupported SubjectPublicKeyInfo curve: group %d",
574 			   crypto_ec_key_group(key));
575 		goto fail;
576 	}
577 
578 	bi->pubkey = key;
579 	return 0;
580 fail:
581 	crypto_ec_key_deinit(key);
582 	return -1;
583 }
584 
585 
586 static struct wpabuf *
587 dpp_parse_jws_prot_hdr(const struct dpp_curve_params *curve,
588 		       const u8 *prot_hdr, u16 prot_hdr_len,
589 		       int *hash_func)
590 {
591 	struct json_token *root, *token;
592 	struct wpabuf *kid = NULL;
593 
594 	root = json_parse((const char *) prot_hdr, prot_hdr_len);
595 	if (!root) {
596 		wpa_printf(MSG_DEBUG,
597 			   "DPP: JSON parsing failed for JWS Protected Header");
598 		goto fail;
599 	}
600 
601 	if (root->type != JSON_OBJECT) {
602 		wpa_printf(MSG_DEBUG,
603 			   "DPP: JWS Protected Header root is not an object");
604 		goto fail;
605 	}
606 
607 	token = json_get_member(root, "typ");
608 	if (!token || token->type != JSON_STRING) {
609 		wpa_printf(MSG_DEBUG, "DPP: No typ string value found");
610 		goto fail;
611 	}
612 	wpa_printf(MSG_DEBUG, "DPP: JWS Protected Header typ=%s",
613 		   token->string);
614 	if (os_strcmp(token->string, "dppCon") != 0) {
615 		wpa_printf(MSG_DEBUG,
616 			   "DPP: Unsupported JWS Protected Header typ=%s",
617 			   token->string);
618 		goto fail;
619 	}
620 
621 	token = json_get_member(root, "alg");
622 	if (!token || token->type != JSON_STRING) {
623 		wpa_printf(MSG_DEBUG, "DPP: No alg string value found");
624 		goto fail;
625 	}
626 	wpa_printf(MSG_DEBUG, "DPP: JWS Protected Header alg=%s",
627 		   token->string);
628 	if (os_strcmp(token->string, curve->jws_alg) != 0) {
629 		wpa_printf(MSG_DEBUG,
630 			   "DPP: Unexpected JWS Protected Header alg=%s (expected %s based on C-sign-key)",
631 			   token->string, curve->jws_alg);
632 		goto fail;
633 	}
634 	if (os_strcmp(token->string, "ES256") == 0 ||
635 	    os_strcmp(token->string, "BS256") == 0) {
636 		*hash_func = CRYPTO_HASH_ALG_SHA256;
637 	} else if (os_strcmp(token->string, "ES384") == 0 ||
638 		   os_strcmp(token->string, "BS384") == 0) {
639 		*hash_func = CRYPTO_HASH_ALG_SHA384;
640 	} else if (os_strcmp(token->string, "ES512") == 0 ||
641 		   os_strcmp(token->string, "BS512") == 0) {
642 		*hash_func = CRYPTO_HASH_ALG_SHA512;
643 	} else {
644 		*hash_func = -1;
645 		wpa_printf(MSG_DEBUG,
646 			   "DPP: Unsupported JWS Protected Header alg=%s",
647 			   token->string);
648 		goto fail;
649 	}
650 
651 	kid = json_get_member_base64url(root, "kid");
652 	if (!kid) {
653 		wpa_printf(MSG_DEBUG, "DPP: No kid string value found");
654 		goto fail;
655 	}
656 	wpa_hexdump_buf(MSG_DEBUG, "DPP: JWS Protected Header kid (decoded)",
657 			kid);
658 
659 fail:
660 	json_free(root);
661 	return kid;
662 }
663 
664 
665 static int dpp_check_pubkey_match(struct crypto_ec_key *pub,
666 				  struct wpabuf *r_hash)
667 {
668 	struct wpabuf *uncomp;
669 	int res;
670 	u8 hash[SHA256_MAC_LEN];
671 	const u8 *addr[1];
672 	size_t len[1];
673 
674 	if (wpabuf_len(r_hash) != SHA256_MAC_LEN)
675 		return -1;
676 	uncomp = crypto_ec_key_get_pubkey_point(pub, 1);
677 	if (!uncomp)
678 		return -1;
679 	addr[0] = wpabuf_head(uncomp);
680 	len[0] = wpabuf_len(uncomp);
681 	wpa_hexdump(MSG_DEBUG, "DPP: Uncompressed public key",
682 		    addr[0], len[0]);
683 	res = sha256_vector(1, addr, len, hash);
684 	wpabuf_free(uncomp);
685 	if (res < 0)
686 		return -1;
687 	if (os_memcmp(hash, wpabuf_head(r_hash), SHA256_MAC_LEN) != 0) {
688 		wpa_printf(MSG_DEBUG,
689 			   "DPP: Received hash value does not match calculated public key hash value");
690 		wpa_hexdump(MSG_DEBUG, "DPP: Calculated hash",
691 			    hash, SHA256_MAC_LEN);
692 		return -1;
693 	}
694 	return 0;
695 }
696 
697 
698 enum dpp_status_error
699 dpp_process_signed_connector(struct dpp_signed_connector_info *info,
700 			     struct crypto_ec_key *csign_pub,
701 			     const char *connector)
702 {
703 	enum dpp_status_error ret = 255;
704 	const char *pos, *end, *signed_start, *signed_end;
705 	struct wpabuf *kid = NULL;
706 	unsigned char *prot_hdr = NULL, *signature = NULL;
707 	size_t prot_hdr_len = 0, signature_len = 0, signed_len;
708 	int res, hash_func = -1;
709 	const struct dpp_curve_params *curve;
710 	u8 *hash = NULL;
711 
712 	curve = dpp_get_curve_ike_group(crypto_ec_key_group(csign_pub));
713 	if (!curve)
714 		goto fail;
715 	wpa_printf(MSG_DEBUG, "DPP: C-sign-key group: %s", curve->jwk_crv);
716 	os_memset(info, 0, sizeof(*info));
717 
718 	signed_start = pos = connector;
719 	end = os_strchr(pos, '.');
720 	if (!end) {
721 		wpa_printf(MSG_DEBUG, "DPP: Missing dot(1) in signedConnector");
722 		ret = DPP_STATUS_INVALID_CONNECTOR;
723 		goto fail;
724 	}
725 	prot_hdr = base64_url_decode(pos, end - pos, &prot_hdr_len);
726 	if (!prot_hdr) {
727 		wpa_printf(MSG_DEBUG,
728 			   "DPP: Failed to base64url decode signedConnector JWS Protected Header");
729 		ret = DPP_STATUS_INVALID_CONNECTOR;
730 		goto fail;
731 	}
732 	wpa_hexdump_ascii(MSG_DEBUG,
733 			  "DPP: signedConnector - JWS Protected Header",
734 			  prot_hdr, prot_hdr_len);
735 	kid = dpp_parse_jws_prot_hdr(curve, prot_hdr, prot_hdr_len, &hash_func);
736 	if (!kid) {
737 		ret = DPP_STATUS_INVALID_CONNECTOR;
738 		goto fail;
739 	}
740 	if (wpabuf_len(kid) != SHA256_MAC_LEN) {
741 		wpa_printf(MSG_DEBUG,
742 			   "DPP: Unexpected signedConnector JWS Protected Header kid length: %u (expected %u)",
743 			   (unsigned int) wpabuf_len(kid), SHA256_MAC_LEN);
744 		ret = DPP_STATUS_INVALID_CONNECTOR;
745 		goto fail;
746 	}
747 
748 	pos = end + 1;
749 	end = os_strchr(pos, '.');
750 	if (!end) {
751 		wpa_printf(MSG_DEBUG,
752 			   "DPP: Missing dot(2) in signedConnector");
753 		ret = DPP_STATUS_INVALID_CONNECTOR;
754 		goto fail;
755 	}
756 	signed_end = end - 1;
757 	info->payload = base64_url_decode(pos, end - pos, &info->payload_len);
758 	if (!info->payload) {
759 		wpa_printf(MSG_DEBUG,
760 			   "DPP: Failed to base64url decode signedConnector JWS Payload");
761 		ret = DPP_STATUS_INVALID_CONNECTOR;
762 		goto fail;
763 	}
764 	wpa_hexdump_ascii(MSG_DEBUG,
765 			  "DPP: signedConnector - JWS Payload",
766 			  info->payload, info->payload_len);
767 	pos = end + 1;
768 	signature = base64_url_decode(pos, os_strlen(pos), &signature_len);
769 	if (!signature) {
770 		wpa_printf(MSG_DEBUG,
771 			   "DPP: Failed to base64url decode signedConnector signature");
772 		ret = DPP_STATUS_INVALID_CONNECTOR;
773 		goto fail;
774 		}
775 	wpa_hexdump(MSG_DEBUG, "DPP: signedConnector - signature",
776 		    signature, signature_len);
777 
778 	if (dpp_check_pubkey_match(csign_pub, kid) < 0) {
779 		ret = DPP_STATUS_NO_MATCH;
780 		goto fail;
781 	}
782 
783 	if (signature_len & 0x01) {
784 		wpa_printf(MSG_DEBUG,
785 			   "DPP: Unexpected signedConnector signature length (%d)",
786 			   (int) signature_len);
787 		ret = DPP_STATUS_INVALID_CONNECTOR;
788 		goto fail;
789 	}
790 
791 	hash = os_malloc(curve->hash_len);
792 	if (!hash)
793 		goto fail;
794 
795 	signed_len = signed_end - signed_start + 1;
796 	if (hash_func == CRYPTO_HASH_ALG_SHA256)
797 		res = sha256_vector(1, (const u8 **) &signed_start, &signed_len,
798 				    hash);
799 	else if (hash_func == CRYPTO_HASH_ALG_SHA384)
800 		res = sha384_vector(1, (const u8 **) &signed_start, &signed_len,
801 				    hash);
802 	else if (hash_func == CRYPTO_HASH_ALG_SHA512)
803 		res = sha512_vector(1, (const u8 **) &signed_start, &signed_len,
804 				    hash);
805 	else
806 		goto fail;
807 
808 	if (res)
809 		goto fail;
810 
811 	res = crypto_ec_key_verify_signature_r_s(csign_pub,
812 						 hash, curve->hash_len,
813 						 signature, signature_len / 2,
814 						 signature + signature_len / 2,
815 						 signature_len / 2);
816 	if (res != 1) {
817 		wpa_printf(MSG_DEBUG,
818 			   "DPP: signedConnector signature check failed (res=%d)",
819 			   res);
820 		ret = DPP_STATUS_INVALID_CONNECTOR;
821 		goto fail;
822 	}
823 
824 	ret = DPP_STATUS_OK;
825 fail:
826 	os_free(hash);
827 	os_free(prot_hdr);
828 	wpabuf_free(kid);
829 	os_free(signature);
830 	return ret;
831 }
832 
833 
834 enum dpp_status_error
835 dpp_check_signed_connector(struct dpp_signed_connector_info *info,
836 			   const u8 *csign_key, size_t csign_key_len,
837 			   const u8 *peer_connector, size_t peer_connector_len)
838 {
839 	struct crypto_ec_key *csign;
840 	char *signed_connector = NULL;
841 	enum dpp_status_error res = DPP_STATUS_INVALID_CONNECTOR;
842 
843 	csign = crypto_ec_key_parse_pub(csign_key, csign_key_len);
844 	if (!csign) {
845 		wpa_printf(MSG_ERROR,
846 			   "DPP: Failed to parse local C-sign-key information");
847 		goto fail;
848 	}
849 
850 	wpa_hexdump_ascii(MSG_DEBUG, "DPP: Peer signedConnector",
851 			  peer_connector, peer_connector_len);
852 	signed_connector = os_malloc(peer_connector_len + 1);
853 	if (!signed_connector)
854 		goto fail;
855 	os_memcpy(signed_connector, peer_connector, peer_connector_len);
856 	signed_connector[peer_connector_len] = '\0';
857 	res = dpp_process_signed_connector(info, csign, signed_connector);
858 fail:
859 	os_free(signed_connector);
860 	crypto_ec_key_deinit(csign);
861 	return res;
862 }
863 
864 
865 int dpp_gen_r_auth(struct dpp_authentication *auth, u8 *r_auth)
866 {
867 	struct wpabuf *pix, *prx, *bix, *brx;
868 	const u8 *addr[7];
869 	size_t len[7];
870 	size_t i, num_elem = 0;
871 	size_t nonce_len;
872 	u8 zero = 0;
873 	int res = -1;
874 
875 	/* R-auth = H(I-nonce | R-nonce | PI.x | PR.x | [BI.x |] BR.x | 0) */
876 	nonce_len = auth->curve->nonce_len;
877 
878 	if (auth->initiator) {
879 		pix = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0);
880 		prx = crypto_ec_key_get_pubkey_point(auth->peer_protocol_key,
881 						     0);
882 		if (auth->own_bi)
883 			bix = crypto_ec_key_get_pubkey_point(
884 				auth->own_bi->pubkey, 0);
885 		else
886 			bix = NULL;
887 		brx = crypto_ec_key_get_pubkey_point(auth->peer_bi->pubkey, 0);
888 	} else {
889 		pix = crypto_ec_key_get_pubkey_point(auth->peer_protocol_key,
890 						     0);
891 		prx = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0);
892 		if (auth->peer_bi)
893 			bix = crypto_ec_key_get_pubkey_point(
894 				auth->peer_bi->pubkey, 0);
895 		else
896 			bix = NULL;
897 		brx = crypto_ec_key_get_pubkey_point(auth->own_bi->pubkey, 0);
898 	}
899 	if (!pix || !prx || !brx)
900 		goto fail;
901 
902 	addr[num_elem] = auth->i_nonce;
903 	len[num_elem] = nonce_len;
904 	num_elem++;
905 
906 	addr[num_elem] = auth->r_nonce;
907 	len[num_elem] = nonce_len;
908 	num_elem++;
909 
910 	addr[num_elem] = wpabuf_head(pix);
911 	len[num_elem] = wpabuf_len(pix) / 2;
912 	num_elem++;
913 
914 	addr[num_elem] = wpabuf_head(prx);
915 	len[num_elem] = wpabuf_len(prx) / 2;
916 	num_elem++;
917 
918 	if (bix) {
919 		addr[num_elem] = wpabuf_head(bix);
920 		len[num_elem] = wpabuf_len(bix) / 2;
921 		num_elem++;
922 	}
923 
924 	addr[num_elem] = wpabuf_head(brx);
925 	len[num_elem] = wpabuf_len(brx) / 2;
926 	num_elem++;
927 
928 	addr[num_elem] = &zero;
929 	len[num_elem] = 1;
930 	num_elem++;
931 
932 	wpa_printf(MSG_DEBUG, "DPP: R-auth hash components");
933 	for (i = 0; i < num_elem; i++)
934 		wpa_hexdump(MSG_DEBUG, "DPP: hash component", addr[i], len[i]);
935 	res = dpp_hash_vector(auth->curve, num_elem, addr, len, r_auth);
936 	if (res == 0)
937 		wpa_hexdump(MSG_DEBUG, "DPP: R-auth", r_auth,
938 			    auth->curve->hash_len);
939 fail:
940 	wpabuf_free(pix);
941 	wpabuf_free(prx);
942 	wpabuf_free(bix);
943 	wpabuf_free(brx);
944 	return res;
945 }
946 
947 
948 int dpp_gen_i_auth(struct dpp_authentication *auth, u8 *i_auth)
949 {
950 	struct wpabuf *pix = NULL, *prx = NULL, *bix = NULL, *brx = NULL;
951 	const u8 *addr[7];
952 	size_t len[7];
953 	size_t i, num_elem = 0;
954 	size_t nonce_len;
955 	u8 one = 1;
956 	int res = -1;
957 
958 	/* I-auth = H(R-nonce | I-nonce | PR.x | PI.x | BR.x | [BI.x |] 1) */
959 	nonce_len = auth->curve->nonce_len;
960 
961 	if (auth->initiator) {
962 		pix = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0);
963 		prx = crypto_ec_key_get_pubkey_point(auth->peer_protocol_key,
964 						     0);
965 		if (auth->own_bi)
966 			bix = crypto_ec_key_get_pubkey_point(
967 				auth->own_bi->pubkey, 0);
968 		else
969 			bix = NULL;
970 		if (!auth->peer_bi)
971 			goto fail;
972 		brx = crypto_ec_key_get_pubkey_point(auth->peer_bi->pubkey, 0);
973 	} else {
974 		pix = crypto_ec_key_get_pubkey_point(auth->peer_protocol_key,
975 						     0);
976 		prx = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0);
977 		if (auth->peer_bi)
978 			bix = crypto_ec_key_get_pubkey_point(
979 				auth->peer_bi->pubkey, 0);
980 		else
981 			bix = NULL;
982 		if (!auth->own_bi)
983 			goto fail;
984 		brx = crypto_ec_key_get_pubkey_point(auth->own_bi->pubkey, 0);
985 	}
986 	if (!pix || !prx || !brx)
987 		goto fail;
988 
989 	addr[num_elem] = auth->r_nonce;
990 	len[num_elem] = nonce_len;
991 	num_elem++;
992 
993 	addr[num_elem] = auth->i_nonce;
994 	len[num_elem] = nonce_len;
995 	num_elem++;
996 
997 	addr[num_elem] = wpabuf_head(prx);
998 	len[num_elem] = wpabuf_len(prx) / 2;
999 	num_elem++;
1000 
1001 	addr[num_elem] = wpabuf_head(pix);
1002 	len[num_elem] = wpabuf_len(pix) / 2;
1003 	num_elem++;
1004 
1005 	addr[num_elem] = wpabuf_head(brx);
1006 	len[num_elem] = wpabuf_len(brx) / 2;
1007 	num_elem++;
1008 
1009 	if (bix) {
1010 		addr[num_elem] = wpabuf_head(bix);
1011 		len[num_elem] = wpabuf_len(bix) / 2;
1012 		num_elem++;
1013 	}
1014 
1015 	addr[num_elem] = &one;
1016 	len[num_elem] = 1;
1017 	num_elem++;
1018 
1019 	wpa_printf(MSG_DEBUG, "DPP: I-auth hash components");
1020 	for (i = 0; i < num_elem; i++)
1021 		wpa_hexdump(MSG_DEBUG, "DPP: hash component", addr[i], len[i]);
1022 	res = dpp_hash_vector(auth->curve, num_elem, addr, len, i_auth);
1023 	if (res == 0)
1024 		wpa_hexdump(MSG_DEBUG, "DPP: I-auth", i_auth,
1025 			    auth->curve->hash_len);
1026 fail:
1027 	wpabuf_free(pix);
1028 	wpabuf_free(prx);
1029 	wpabuf_free(bix);
1030 	wpabuf_free(brx);
1031 	return res;
1032 }
1033 
1034 
1035 int dpp_auth_derive_l_responder(struct dpp_authentication *auth)
1036 {
1037 	struct crypto_ec *ec;
1038 	struct crypto_ec_point *L = NULL;
1039 	const struct crypto_ec_point *BI;
1040 	const struct crypto_bignum *bR, *pR, *q;
1041 	struct crypto_bignum *sum = NULL, *lx = NULL;
1042 	int ret = -1;
1043 
1044 	/* L = ((bR + pR) modulo q) * BI */
1045 
1046 	ec = crypto_ec_init(crypto_ec_key_group(auth->peer_bi->pubkey));
1047 	if (!ec)
1048 		goto fail;
1049 
1050 	q = crypto_ec_get_order(ec);
1051 	BI = crypto_ec_key_get_public_key(auth->peer_bi->pubkey);
1052 	bR = crypto_ec_key_get_private_key(auth->own_bi->pubkey);
1053 	pR = crypto_ec_key_get_private_key(auth->own_protocol_key);
1054 	sum = crypto_bignum_init();
1055 	L = crypto_ec_point_init(ec);
1056 	lx = crypto_bignum_init();
1057 	if (!q || !BI || !bR || !pR || !sum || !L || !lx ||
1058 	    crypto_bignum_addmod(bR, pR, q, sum) ||
1059 	    crypto_ec_point_mul(ec, BI, sum, L) ||
1060 	    crypto_ec_point_x(ec, L, lx) ||
1061 	    crypto_bignum_to_bin(lx, auth->Lx, sizeof(auth->Lx),
1062 				 auth->secret_len) < 0)
1063 		goto fail;
1064 
1065 	wpa_hexdump_key(MSG_DEBUG, "DPP: L.x", auth->Lx, auth->secret_len);
1066 	auth->Lx_len = auth->secret_len;
1067 	ret = 0;
1068 fail:
1069 	crypto_bignum_deinit(lx, 1);
1070 	crypto_bignum_deinit(sum, 1);
1071 	crypto_ec_point_deinit(L, 1);
1072 	crypto_ec_deinit(ec);
1073 	return ret;
1074 }
1075 
1076 
1077 int dpp_auth_derive_l_initiator(struct dpp_authentication *auth)
1078 {
1079 	struct crypto_ec *ec;
1080 	struct crypto_ec_point *L = NULL, *sum = NULL;
1081 	const struct crypto_ec_point *BR, *PR;
1082 	const struct crypto_bignum *bI;
1083 	struct crypto_bignum *lx = NULL;
1084 	int ret = -1;
1085 
1086 	/* L = bI * (BR + PR) */
1087 
1088 	ec = crypto_ec_init(crypto_ec_key_group(auth->peer_bi->pubkey));
1089 	if (!ec)
1090 		goto fail;
1091 
1092 	BR = crypto_ec_key_get_public_key(auth->peer_bi->pubkey);
1093 	PR = crypto_ec_key_get_public_key(auth->peer_protocol_key);
1094 	bI = crypto_ec_key_get_private_key(auth->own_bi->pubkey);
1095 	sum = crypto_ec_point_init(ec);
1096 	L = crypto_ec_point_init(ec);
1097 	lx = crypto_bignum_init();
1098 	if (!BR || !PR || !bI || !sum || !L || !lx ||
1099 	    crypto_ec_point_add(ec, BR, PR, sum) ||
1100 	    crypto_ec_point_mul(ec, sum, bI, L) ||
1101 	    crypto_ec_point_x(ec, L, lx) ||
1102 	    crypto_bignum_to_bin(lx, auth->Lx, sizeof(auth->Lx),
1103 				 auth->secret_len) < 0)
1104 		goto fail;
1105 
1106 	wpa_hexdump_key(MSG_DEBUG, "DPP: L.x", auth->Lx, auth->secret_len);
1107 	auth->Lx_len = auth->secret_len;
1108 	ret = 0;
1109 fail:
1110 	crypto_bignum_deinit(lx, 1);
1111 	crypto_ec_point_deinit(sum, 1);
1112 	crypto_ec_point_deinit(L, 1);
1113 	crypto_ec_deinit(ec);
1114 	return ret;
1115 }
1116 
1117 
1118 int dpp_derive_pmk(const u8 *Nx, size_t Nx_len, u8 *pmk, unsigned int hash_len)
1119 {
1120 	u8 salt[DPP_MAX_HASH_LEN], prk[DPP_MAX_HASH_LEN];
1121 	const char *info = "DPP PMK";
1122 	int res;
1123 
1124 	/* PMK = HKDF(<>, "DPP PMK", N.x) */
1125 
1126 	/* HKDF-Extract(<>, N.x) */
1127 	os_memset(salt, 0, hash_len);
1128 	if (dpp_hmac(hash_len, salt, hash_len, Nx, Nx_len, prk) < 0)
1129 		return -1;
1130 	wpa_hexdump_key(MSG_DEBUG, "DPP: PRK = HKDF-Extract(<>, IKM=N.x)",
1131 			prk, hash_len);
1132 
1133 	/* HKDF-Expand(PRK, info, L) */
1134 	res = dpp_hkdf_expand(hash_len, prk, hash_len, info, pmk, hash_len);
1135 	os_memset(prk, 0, hash_len);
1136 	if (res < 0)
1137 		return -1;
1138 
1139 	wpa_hexdump_key(MSG_DEBUG, "DPP: PMK = HKDF-Expand(PRK, info, L)",
1140 			pmk, hash_len);
1141 	return 0;
1142 }
1143 
1144 
1145 int dpp_derive_pmkid(const struct dpp_curve_params *curve,
1146 		     struct crypto_ec_key *own_key,
1147 		     struct crypto_ec_key *peer_key, u8 *pmkid)
1148 {
1149 	struct wpabuf *nkx, *pkx;
1150 	int ret = -1, res;
1151 	const u8 *addr[2];
1152 	size_t len[2];
1153 	u8 hash[SHA256_MAC_LEN];
1154 
1155 	/* PMKID = Truncate-128(H(min(NK.x, PK.x) | max(NK.x, PK.x))) */
1156 	nkx = crypto_ec_key_get_pubkey_point(own_key, 0);
1157 	pkx = crypto_ec_key_get_pubkey_point(peer_key, 0);
1158 	if (!nkx || !pkx)
1159 		goto fail;
1160 	addr[0] = wpabuf_head(nkx);
1161 	len[0] = wpabuf_len(nkx) / 2;
1162 	addr[1] = wpabuf_head(pkx);
1163 	len[1] = wpabuf_len(pkx) / 2;
1164 	if (len[0] != len[1])
1165 		goto fail;
1166 	if (os_memcmp(addr[0], addr[1], len[0]) > 0) {
1167 		addr[0] = wpabuf_head(pkx);
1168 		addr[1] = wpabuf_head(nkx);
1169 	}
1170 	wpa_hexdump(MSG_DEBUG, "DPP: PMKID hash payload 1", addr[0], len[0]);
1171 	wpa_hexdump(MSG_DEBUG, "DPP: PMKID hash payload 2", addr[1], len[1]);
1172 	res = sha256_vector(2, addr, len, hash);
1173 	if (res < 0)
1174 		goto fail;
1175 	wpa_hexdump(MSG_DEBUG, "DPP: PMKID hash output", hash, SHA256_MAC_LEN);
1176 	os_memcpy(pmkid, hash, PMKID_LEN);
1177 	wpa_hexdump(MSG_DEBUG, "DPP: PMKID", pmkid, PMKID_LEN);
1178 	ret = 0;
1179 fail:
1180 	wpabuf_free(nkx);
1181 	wpabuf_free(pkx);
1182 	return ret;
1183 }
1184 
1185 
1186 /* Role-specific elements for PKEX */
1187 
1188 /* NIST P-256 */
1189 static const u8 pkex_init_x_p256[32] = {
1190 	0x56, 0x26, 0x12, 0xcf, 0x36, 0x48, 0xfe, 0x0b,
1191 	0x07, 0x04, 0xbb, 0x12, 0x22, 0x50, 0xb2, 0x54,
1192 	0xb1, 0x94, 0x64, 0x7e, 0x54, 0xce, 0x08, 0x07,
1193 	0x2e, 0xec, 0xca, 0x74, 0x5b, 0x61, 0x2d, 0x25
1194  };
1195 static const u8 pkex_init_y_p256[32] = {
1196 	0x3e, 0x44, 0xc7, 0xc9, 0x8c, 0x1c, 0xa1, 0x0b,
1197 	0x20, 0x09, 0x93, 0xb2, 0xfd, 0xe5, 0x69, 0xdc,
1198 	0x75, 0xbc, 0xad, 0x33, 0xc1, 0xe7, 0xc6, 0x45,
1199 	0x4d, 0x10, 0x1e, 0x6a, 0x3d, 0x84, 0x3c, 0xa4
1200  };
1201 static const u8 pkex_resp_x_p256[32] = {
1202 	0x1e, 0xa4, 0x8a, 0xb1, 0xa4, 0xe8, 0x42, 0x39,
1203 	0xad, 0x73, 0x07, 0xf2, 0x34, 0xdf, 0x57, 0x4f,
1204 	0xc0, 0x9d, 0x54, 0xbe, 0x36, 0x1b, 0x31, 0x0f,
1205 	0x59, 0x91, 0x52, 0x33, 0xac, 0x19, 0x9d, 0x76
1206 };
1207 static const u8 pkex_resp_y_p256[32] = {
1208 	0xd9, 0xfb, 0xf6, 0xb9, 0xf5, 0xfa, 0xdf, 0x19,
1209 	0x58, 0xd8, 0x3e, 0xc9, 0x89, 0x7a, 0x35, 0xc1,
1210 	0xbd, 0xe9, 0x0b, 0x77, 0x7a, 0xcb, 0x91, 0x2a,
1211 	0xe8, 0x21, 0x3f, 0x47, 0x52, 0x02, 0x4d, 0x67
1212 };
1213 
1214 /* NIST P-384 */
1215 static const u8 pkex_init_x_p384[48] = {
1216 	0x95, 0x3f, 0x42, 0x9e, 0x50, 0x7f, 0xf9, 0xaa,
1217 	0xac, 0x1a, 0xf2, 0x85, 0x2e, 0x64, 0x91, 0x68,
1218 	0x64, 0xc4, 0x3c, 0xb7, 0x5c, 0xf8, 0xc9, 0x53,
1219 	0x6e, 0x58, 0x4c, 0x7f, 0xc4, 0x64, 0x61, 0xac,
1220 	0x51, 0x8a, 0x6f, 0xfe, 0xab, 0x74, 0xe6, 0x12,
1221 	0x81, 0xac, 0x38, 0x5d, 0x41, 0xe6, 0xb9, 0xa3
1222 };
1223 static const u8 pkex_init_y_p384[48] = {
1224 	0x76, 0x2f, 0x68, 0x84, 0xa6, 0xb0, 0x59, 0x29,
1225 	0x83, 0xa2, 0x6c, 0xa4, 0x6c, 0x3b, 0xf8, 0x56,
1226 	0x76, 0x11, 0x2a, 0x32, 0x90, 0xbd, 0x07, 0xc7,
1227 	0x37, 0x39, 0x9d, 0xdb, 0x96, 0xf3, 0x2b, 0xb6,
1228 	0x27, 0xbb, 0x29, 0x3c, 0x17, 0x33, 0x9d, 0x94,
1229 	0xc3, 0xda, 0xac, 0x46, 0xb0, 0x8e, 0x07, 0x18
1230 };
1231 static const u8 pkex_resp_x_p384[48] = {
1232 	0xad, 0xbe, 0xd7, 0x1d, 0x3a, 0x71, 0x64, 0x98,
1233 	0x5f, 0xb4, 0xd6, 0x4b, 0x50, 0xd0, 0x84, 0x97,
1234 	0x4b, 0x7e, 0x57, 0x70, 0xd2, 0xd9, 0xf4, 0x92,
1235 	0x2a, 0x3f, 0xce, 0x99, 0xc5, 0x77, 0x33, 0x44,
1236 	0x14, 0x56, 0x92, 0xcb, 0xae, 0x46, 0x64, 0xdf,
1237 	0xe0, 0xbb, 0xd7, 0xb1, 0x29, 0x20, 0x72, 0xdf
1238 };
1239 static const u8 pkex_resp_y_p384[48] = {
1240 	0xab, 0xa7, 0xdf, 0x52, 0xaa, 0xe2, 0x35, 0x0c,
1241 	0xe3, 0x75, 0x32, 0xe6, 0xbf, 0x06, 0xc8, 0x7c,
1242 	0x38, 0x29, 0x4c, 0xec, 0x82, 0xac, 0xd7, 0xa3,
1243 	0x09, 0xd2, 0x0e, 0x22, 0x5a, 0x74, 0x52, 0xa1,
1244 	0x7e, 0x54, 0x4e, 0xfe, 0xc6, 0x29, 0x33, 0x63,
1245 	0x15, 0xe1, 0x7b, 0xe3, 0x40, 0x1c, 0xca, 0x06
1246 };
1247 
1248 /* NIST P-521 */
1249 static const u8 pkex_init_x_p521[66] = {
1250 	0x00, 0x16, 0x20, 0x45, 0x19, 0x50, 0x95, 0x23,
1251 	0x0d, 0x24, 0xbe, 0x00, 0x87, 0xdc, 0xfa, 0xf0,
1252 	0x58, 0x9a, 0x01, 0x60, 0x07, 0x7a, 0xca, 0x76,
1253 	0x01, 0xab, 0x2d, 0x5a, 0x46, 0xcd, 0x2c, 0xb5,
1254 	0x11, 0x9a, 0xff, 0xaa, 0x48, 0x04, 0x91, 0x38,
1255 	0xcf, 0x86, 0xfc, 0xa4, 0xa5, 0x0f, 0x47, 0x01,
1256 	0x80, 0x1b, 0x30, 0xa3, 0xae, 0xe8, 0x1c, 0x2e,
1257 	0xea, 0xcc, 0xf0, 0x03, 0x9f, 0x77, 0x4c, 0x8d,
1258 	0x97, 0x76
1259 };
1260 static const u8 pkex_init_y_p521[66] = {
1261 	0x00, 0xb3, 0x8e, 0x02, 0xe4, 0x2a, 0x63, 0x59,
1262 	0x12, 0xc6, 0x10, 0xba, 0x3a, 0xf9, 0x02, 0x99,
1263 	0x3f, 0x14, 0xf0, 0x40, 0xde, 0x5c, 0xc9, 0x8b,
1264 	0x02, 0x55, 0xfa, 0x91, 0xb1, 0xcc, 0x6a, 0xbd,
1265 	0xe5, 0x62, 0xc0, 0xc5, 0xe3, 0xa1, 0x57, 0x9f,
1266 	0x08, 0x1a, 0xa6, 0xe2, 0xf8, 0x55, 0x90, 0xbf,
1267 	0xf5, 0xa6, 0xc3, 0xd8, 0x52, 0x1f, 0xb7, 0x02,
1268 	0x2e, 0x7c, 0xc8, 0xb3, 0x20, 0x1e, 0x79, 0x8d,
1269 	0x03, 0xa8
1270 };
1271 static const u8 pkex_resp_x_p521[66] = {
1272 	0x00, 0x79, 0xe4, 0x4d, 0x6b, 0x5e, 0x12, 0x0a,
1273 	0x18, 0x2c, 0xb3, 0x05, 0x77, 0x0f, 0xc3, 0x44,
1274 	0x1a, 0xcd, 0x78, 0x46, 0x14, 0xee, 0x46, 0x3f,
1275 	0xab, 0xc9, 0x59, 0x7c, 0x85, 0xa0, 0xc2, 0xfb,
1276 	0x02, 0x32, 0x99, 0xde, 0x5d, 0xe1, 0x0d, 0x48,
1277 	0x2d, 0x71, 0x7d, 0x8d, 0x3f, 0x61, 0x67, 0x9e,
1278 	0x2b, 0x8b, 0x12, 0xde, 0x10, 0x21, 0x55, 0x0a,
1279 	0x5b, 0x2d, 0xe8, 0x05, 0x09, 0xf6, 0x20, 0x97,
1280 	0x84, 0xb4
1281 };
1282 static const u8 pkex_resp_y_p521[66] = {
1283 	0x00, 0x46, 0x63, 0x39, 0xbe, 0xcd, 0xa4, 0x2d,
1284 	0xca, 0x27, 0x74, 0xd4, 0x1b, 0x91, 0x33, 0x20,
1285 	0x83, 0xc7, 0x3b, 0xa4, 0x09, 0x8b, 0x8e, 0xa3,
1286 	0x88, 0xe9, 0x75, 0x7f, 0x56, 0x7b, 0x38, 0x84,
1287 	0x62, 0x02, 0x7c, 0x90, 0x51, 0x07, 0xdb, 0xe9,
1288 	0xd0, 0xde, 0xda, 0x9a, 0x5d, 0xe5, 0x94, 0xd2,
1289 	0xcf, 0x9d, 0x4c, 0x33, 0x91, 0xa6, 0xc3, 0x80,
1290 	0xa7, 0x6e, 0x7e, 0x8d, 0xf8, 0x73, 0x6e, 0x53,
1291 	0xce, 0xe1
1292 };
1293 
1294 /* Brainpool P-256r1 */
1295 static const u8 pkex_init_x_bp_p256r1[32] = {
1296 	0x46, 0x98, 0x18, 0x6c, 0x27, 0xcd, 0x4b, 0x10,
1297 	0x7d, 0x55, 0xa3, 0xdd, 0x89, 0x1f, 0x9f, 0xca,
1298 	0xc7, 0x42, 0x5b, 0x8a, 0x23, 0xed, 0xf8, 0x75,
1299 	0xac, 0xc7, 0xe9, 0x8d, 0xc2, 0x6f, 0xec, 0xd8
1300 };
1301 static const u8 pkex_init_y_bp_p256r1[32] = {
1302 	0x93, 0xca, 0xef, 0xa9, 0x66, 0x3e, 0x87, 0xcd,
1303 	0x52, 0x6e, 0x54, 0x13, 0xef, 0x31, 0x67, 0x30,
1304 	0x15, 0x13, 0x9d, 0x6d, 0xc0, 0x95, 0x32, 0xbe,
1305 	0x4f, 0xab, 0x5d, 0xf7, 0xbf, 0x5e, 0xaa, 0x0b
1306 };
1307 static const u8 pkex_resp_x_bp_p256r1[32] = {
1308 	0x90, 0x18, 0x84, 0xc9, 0xdc, 0xcc, 0xb5, 0x2f,
1309 	0x4a, 0x3f, 0x4f, 0x18, 0x0a, 0x22, 0x56, 0x6a,
1310 	0xa9, 0xef, 0xd4, 0xe6, 0xc3, 0x53, 0xc2, 0x1a,
1311 	0x23, 0x54, 0xdd, 0x08, 0x7e, 0x10, 0xd8, 0xe3
1312 };
1313 static const u8 pkex_resp_y_bp_p256r1[32] = {
1314 	0x2a, 0xfa, 0x98, 0x9b, 0xe3, 0xda, 0x30, 0xfd,
1315 	0x32, 0x28, 0xcb, 0x66, 0xfb, 0x40, 0x7f, 0xf2,
1316 	0xb2, 0x25, 0x80, 0x82, 0x44, 0x85, 0x13, 0x7e,
1317 	0x4b, 0xb5, 0x06, 0xc0, 0x03, 0x69, 0x23, 0x64
1318 };
1319 
1320 /* Brainpool P-384r1 */
1321 static const u8 pkex_init_x_bp_p384r1[48] = {
1322 	0x0a, 0x2c, 0xeb, 0x49, 0x5e, 0xb7, 0x23, 0xbd,
1323 	0x20, 0x5b, 0xe0, 0x49, 0xdf, 0xcf, 0xcf, 0x19,
1324 	0x37, 0x36, 0xe1, 0x2f, 0x59, 0xdb, 0x07, 0x06,
1325 	0xb5, 0xeb, 0x2d, 0xae, 0xc2, 0xb2, 0x38, 0x62,
1326 	0xa6, 0x73, 0x09, 0xa0, 0x6c, 0x0a, 0xa2, 0x30,
1327 	0x99, 0xeb, 0xf7, 0x1e, 0x47, 0xb9, 0x5e, 0xbe
1328 };
1329 static const u8 pkex_init_y_bp_p384r1[48] = {
1330 	0x54, 0x76, 0x61, 0x65, 0x75, 0x5a, 0x2f, 0x99,
1331 	0x39, 0x73, 0xca, 0x6c, 0xf9, 0xf7, 0x12, 0x86,
1332 	0x54, 0xd5, 0xd4, 0xad, 0x45, 0x7b, 0xbf, 0x32,
1333 	0xee, 0x62, 0x8b, 0x9f, 0x52, 0xe8, 0xa0, 0xc9,
1334 	0xb7, 0x9d, 0xd1, 0x09, 0xb4, 0x79, 0x1c, 0x3e,
1335 	0x1a, 0xbf, 0x21, 0x45, 0x66, 0x6b, 0x02, 0x52
1336 };
1337 static const u8 pkex_resp_x_bp_p384r1[48] = {
1338 	0x03, 0xa2, 0x57, 0xef, 0xe8, 0x51, 0x21, 0xa0,
1339 	0xc8, 0x9e, 0x21, 0x02, 0xb5, 0x9a, 0x36, 0x25,
1340 	0x74, 0x22, 0xd1, 0xf2, 0x1b, 0xa8, 0x9a, 0x9b,
1341 	0x97, 0xbc, 0x5a, 0xeb, 0x26, 0x15, 0x09, 0x71,
1342 	0x77, 0x59, 0xec, 0x8b, 0xb7, 0xe1, 0xe8, 0xce,
1343 	0x65, 0xb8, 0xaf, 0xf8, 0x80, 0xae, 0x74, 0x6c
1344 };
1345 static const u8 pkex_resp_y_bp_p384r1[48] = {
1346 	0x2f, 0xd9, 0x6a, 0xc7, 0x3e, 0xec, 0x76, 0x65,
1347 	0x2d, 0x38, 0x7f, 0xec, 0x63, 0x26, 0x3f, 0x04,
1348 	0xd8, 0x4e, 0xff, 0xe1, 0x0a, 0x51, 0x74, 0x70,
1349 	0xe5, 0x46, 0x63, 0x7f, 0x5c, 0xc0, 0xd1, 0x7c,
1350 	0xfb, 0x2f, 0xea, 0xe2, 0xd8, 0x0f, 0x84, 0xcb,
1351 	0xe9, 0x39, 0x5c, 0x64, 0xfe, 0xcb, 0x2f, 0xf1
1352 };
1353 
1354 /* Brainpool P-512r1 */
1355 static const u8 pkex_init_x_bp_p512r1[64] = {
1356 	0x4c, 0xe9, 0xb6, 0x1c, 0xe2, 0x00, 0x3c, 0x9c,
1357 	0xa9, 0xc8, 0x56, 0x52, 0xaf, 0x87, 0x3e, 0x51,
1358 	0x9c, 0xbb, 0x15, 0x31, 0x1e, 0xc1, 0x05, 0xfc,
1359 	0x7c, 0x77, 0xd7, 0x37, 0x61, 0x27, 0xd0, 0x95,
1360 	0x98, 0xee, 0x5d, 0xa4, 0x3d, 0x09, 0xdb, 0x3d,
1361 	0xfa, 0x89, 0x9e, 0x7f, 0xa6, 0xa6, 0x9c, 0xff,
1362 	0x83, 0x5c, 0x21, 0x6c, 0x3e, 0xf2, 0xfe, 0xdc,
1363 	0x63, 0xe4, 0xd1, 0x0e, 0x75, 0x45, 0x69, 0x0f
1364 };
1365 static const u8 pkex_init_y_bp_p512r1[64] = {
1366 	0x50, 0xb5, 0x9b, 0xfa, 0x45, 0x67, 0x75, 0x94,
1367 	0x44, 0xe7, 0x68, 0xb0, 0xeb, 0x3e, 0xb3, 0xb8,
1368 	0xf9, 0x99, 0x05, 0xef, 0xae, 0x6c, 0xbc, 0xe3,
1369 	0xe1, 0xd2, 0x51, 0x54, 0xdf, 0x59, 0xd4, 0x45,
1370 	0x41, 0x3a, 0xa8, 0x0b, 0x76, 0x32, 0x44, 0x0e,
1371 	0x07, 0x60, 0x3a, 0x6e, 0xbe, 0xfe, 0xe0, 0x58,
1372 	0x52, 0xa0, 0xaa, 0x8b, 0xd8, 0x5b, 0xf2, 0x71,
1373 	0x11, 0x9a, 0x9e, 0x8f, 0x1a, 0xd1, 0xc9, 0x99
1374 };
1375 static const u8 pkex_resp_x_bp_p512r1[64] = {
1376 	0x2a, 0x60, 0x32, 0x27, 0xa1, 0xe6, 0x94, 0x72,
1377 	0x1c, 0x48, 0xbe, 0xc5, 0x77, 0x14, 0x30, 0x76,
1378 	0xe4, 0xbf, 0xf7, 0x7b, 0xc5, 0xfd, 0xdf, 0x19,
1379 	0x1e, 0x0f, 0xdf, 0x1c, 0x40, 0xfa, 0x34, 0x9e,
1380 	0x1f, 0x42, 0x24, 0xa3, 0x2c, 0xd5, 0xc7, 0xc9,
1381 	0x7b, 0x47, 0x78, 0x96, 0xf1, 0x37, 0x0e, 0x88,
1382 	0xcb, 0xa6, 0x52, 0x29, 0xd7, 0xa8, 0x38, 0x29,
1383 	0x8e, 0x6e, 0x23, 0x47, 0xd4, 0x4b, 0x70, 0x3e
1384 };
1385 static const u8 pkex_resp_y_bp_p512r1[64] = {
1386 	0x80, 0x1f, 0x43, 0xd2, 0x17, 0x35, 0xec, 0x81,
1387 	0xd9, 0x4b, 0xdc, 0x81, 0x19, 0xd9, 0x5f, 0x68,
1388 	0x16, 0x84, 0xfe, 0x63, 0x4b, 0x8d, 0x5d, 0xaa,
1389 	0x88, 0x4a, 0x47, 0x48, 0xd4, 0xea, 0xab, 0x7d,
1390 	0x6a, 0xbf, 0xe1, 0x28, 0x99, 0x6a, 0x87, 0x1c,
1391 	0x30, 0xb4, 0x44, 0x2d, 0x75, 0xac, 0x35, 0x09,
1392 	0x73, 0x24, 0x3d, 0xb4, 0x43, 0xb1, 0xc1, 0x56,
1393 	0x56, 0xad, 0x30, 0x87, 0xf4, 0xc3, 0x00, 0xc7
1394 };
1395 
1396 
1397 static struct crypto_ec_key *
1398 dpp_pkex_get_role_elem(const struct dpp_curve_params *curve, int init)
1399 {
1400 	const u8 *x, *y;
1401 
1402 	switch (curve->ike_group) {
1403 	case 19:
1404 		x = init ? pkex_init_x_p256 : pkex_resp_x_p256;
1405 		y = init ? pkex_init_y_p256 : pkex_resp_y_p256;
1406 		break;
1407 	case 20:
1408 		x = init ? pkex_init_x_p384 : pkex_resp_x_p384;
1409 		y = init ? pkex_init_y_p384 : pkex_resp_y_p384;
1410 		break;
1411 	case 21:
1412 		x = init ? pkex_init_x_p521 : pkex_resp_x_p521;
1413 		y = init ? pkex_init_y_p521 : pkex_resp_y_p521;
1414 		break;
1415 	case 28:
1416 		x = init ? pkex_init_x_bp_p256r1 : pkex_resp_x_bp_p256r1;
1417 		y = init ? pkex_init_y_bp_p256r1 : pkex_resp_y_bp_p256r1;
1418 		break;
1419 	case 29:
1420 		x = init ? pkex_init_x_bp_p384r1 : pkex_resp_x_bp_p384r1;
1421 		y = init ? pkex_init_y_bp_p384r1 : pkex_resp_y_bp_p384r1;
1422 		break;
1423 	case 30:
1424 		x = init ? pkex_init_x_bp_p512r1 : pkex_resp_x_bp_p512r1;
1425 		y = init ? pkex_init_y_bp_p512r1 : pkex_resp_y_bp_p512r1;
1426 		break;
1427 	default:
1428 		return NULL;
1429 	}
1430 
1431 	return crypto_ec_key_set_pub(curve->ike_group, x, y, curve->prime_len);
1432 }
1433 
1434 
1435 struct crypto_ec_point *
1436 dpp_pkex_derive_Qi(const struct dpp_curve_params *curve, const u8 *mac_init,
1437 		   const char *code, const char *identifier,
1438 		   struct crypto_ec **ret_ec)
1439 {
1440 	u8 hash[DPP_MAX_HASH_LEN];
1441 	const u8 *addr[3];
1442 	size_t len[3];
1443 	unsigned int num_elem = 0;
1444 	struct crypto_ec_point *Qi = NULL;
1445 	struct crypto_ec_key *Pi_key = NULL;
1446 	const struct crypto_ec_point *Pi = NULL;
1447 	struct crypto_bignum *hash_bn = NULL;
1448 	struct crypto_ec *ec = NULL;
1449 
1450 	/* Qi = H(MAC-Initiator | [identifier |] code) * Pi */
1451 
1452 	wpa_printf(MSG_DEBUG, "DPP: MAC-Initiator: " MACSTR, MAC2STR(mac_init));
1453 	addr[num_elem] = mac_init;
1454 	len[num_elem] = ETH_ALEN;
1455 	num_elem++;
1456 	if (identifier) {
1457 		wpa_printf(MSG_DEBUG, "DPP: code identifier: %s",
1458 			   identifier);
1459 		addr[num_elem] = (const u8 *) identifier;
1460 		len[num_elem] = os_strlen(identifier);
1461 		num_elem++;
1462 	}
1463 	wpa_hexdump_ascii_key(MSG_DEBUG, "DPP: code", code, os_strlen(code));
1464 	addr[num_elem] = (const u8 *) code;
1465 	len[num_elem] = os_strlen(code);
1466 	num_elem++;
1467 	if (dpp_hash_vector(curve, num_elem, addr, len, hash) < 0)
1468 		goto fail;
1469 	wpa_hexdump_key(MSG_DEBUG,
1470 			"DPP: H(MAC-Initiator | [identifier |] code)",
1471 			hash, curve->hash_len);
1472 	Pi_key = dpp_pkex_get_role_elem(curve, 1);
1473 	if (!Pi_key)
1474 		goto fail;
1475 	dpp_debug_print_key("DPP: Pi", Pi_key);
1476 
1477 	ec = crypto_ec_init(curve->ike_group);
1478 	if (!ec)
1479 		goto fail;
1480 
1481 	Pi = crypto_ec_key_get_public_key(Pi_key);
1482 	Qi = crypto_ec_point_init(ec);
1483 	hash_bn = crypto_bignum_init_set(hash, curve->hash_len);
1484 	if (!Pi || !Qi || !hash_bn || crypto_ec_point_mul(ec, Pi, hash_bn, Qi))
1485 		goto fail;
1486 
1487 	if (crypto_ec_point_is_at_infinity(ec, Qi)) {
1488 		wpa_printf(MSG_INFO, "DPP: Qi is the point-at-infinity");
1489 		goto fail;
1490 	}
1491 	crypto_ec_point_debug_print(ec, Qi, "DPP: Qi");
1492 out:
1493 	crypto_ec_key_deinit(Pi_key);
1494 	crypto_bignum_deinit(hash_bn, 1);
1495 	if (ret_ec && Qi)
1496 		*ret_ec = ec;
1497 	else
1498 		crypto_ec_deinit(ec);
1499 	return Qi;
1500 fail:
1501 	crypto_ec_point_deinit(Qi, 1);
1502 	Qi = NULL;
1503 	goto out;
1504 }
1505 
1506 
1507 struct crypto_ec_point *
1508 dpp_pkex_derive_Qr(const struct dpp_curve_params *curve, const u8 *mac_resp,
1509 		   const char *code, const char *identifier,
1510 		   struct crypto_ec **ret_ec)
1511 {
1512 	u8 hash[DPP_MAX_HASH_LEN];
1513 	const u8 *addr[3];
1514 	size_t len[3];
1515 	unsigned int num_elem = 0;
1516 	struct crypto_ec_point *Qr = NULL;
1517 	struct crypto_ec_key *Pr_key = NULL;
1518 	const struct crypto_ec_point *Pr = NULL;
1519 	struct crypto_bignum *hash_bn = NULL;
1520 	struct crypto_ec *ec = NULL;
1521 
1522 	/* Qr = H(MAC-Responder | | [identifier | ] code) * Pr */
1523 
1524 	wpa_printf(MSG_DEBUG, "DPP: MAC-Responder: " MACSTR, MAC2STR(mac_resp));
1525 	addr[num_elem] = mac_resp;
1526 	len[num_elem] = ETH_ALEN;
1527 	num_elem++;
1528 	if (identifier) {
1529 		wpa_printf(MSG_DEBUG, "DPP: code identifier: %s",
1530 			   identifier);
1531 		addr[num_elem] = (const u8 *) identifier;
1532 		len[num_elem] = os_strlen(identifier);
1533 		num_elem++;
1534 	}
1535 	wpa_hexdump_ascii_key(MSG_DEBUG, "DPP: code", code, os_strlen(code));
1536 	addr[num_elem] = (const u8 *) code;
1537 	len[num_elem] = os_strlen(code);
1538 	num_elem++;
1539 	if (dpp_hash_vector(curve, num_elem, addr, len, hash) < 0)
1540 		goto fail;
1541 	wpa_hexdump_key(MSG_DEBUG,
1542 			"DPP: H(MAC-Responder | [identifier |] code)",
1543 			hash, curve->hash_len);
1544 	Pr_key = dpp_pkex_get_role_elem(curve, 0);
1545 	if (!Pr_key)
1546 		goto fail;
1547 	dpp_debug_print_key("DPP: Pr", Pr_key);
1548 
1549 	ec = crypto_ec_init(curve->ike_group);
1550 	if (!ec)
1551 		goto fail;
1552 
1553 	Pr = crypto_ec_key_get_public_key(Pr_key);
1554 	Qr = crypto_ec_point_init(ec);
1555 	hash_bn = crypto_bignum_init_set(hash, curve->hash_len);
1556 	if (!Pr || !Qr || !hash_bn || crypto_ec_point_mul(ec, Pr, hash_bn, Qr))
1557 		goto fail;
1558 
1559 	if (crypto_ec_point_is_at_infinity(ec, Qr)) {
1560 		wpa_printf(MSG_INFO, "DPP: Qr is the point-at-infinity");
1561 		goto fail;
1562 	}
1563 	crypto_ec_point_debug_print(ec, Qr, "DPP: Qr");
1564 
1565 out:
1566 	crypto_ec_key_deinit(Pr_key);
1567 	crypto_bignum_deinit(hash_bn, 1);
1568 	if (ret_ec && Qr)
1569 		*ret_ec = ec;
1570 	else
1571 		crypto_ec_deinit(ec);
1572 	return Qr;
1573 fail:
1574 	crypto_ec_point_deinit(Qr, 1);
1575 	Qr = NULL;
1576 	goto out;
1577 }
1578 
1579 
1580 int dpp_pkex_derive_z(const u8 *mac_init, const u8 *mac_resp,
1581 		      const u8 *Mx, size_t Mx_len,
1582 		      const u8 *Nx, size_t Nx_len,
1583 		      const char *code,
1584 		      const u8 *Kx, size_t Kx_len,
1585 		      u8 *z, unsigned int hash_len)
1586 {
1587 	u8 salt[DPP_MAX_HASH_LEN], prk[DPP_MAX_HASH_LEN];
1588 	int res;
1589 	u8 *info, *pos;
1590 	size_t info_len;
1591 
1592 	/* z = HKDF(<>, MAC-Initiator | MAC-Responder | M.x | N.x | code, K.x)
1593 	 */
1594 
1595 	/* HKDF-Extract(<>, IKM=K.x) */
1596 	os_memset(salt, 0, hash_len);
1597 	if (dpp_hmac(hash_len, salt, hash_len, Kx, Kx_len, prk) < 0)
1598 		return -1;
1599 	wpa_hexdump_key(MSG_DEBUG, "DPP: PRK = HKDF-Extract(<>, IKM)",
1600 			prk, hash_len);
1601 	info_len = 2 * ETH_ALEN + Mx_len + Nx_len + os_strlen(code);
1602 	info = os_malloc(info_len);
1603 	if (!info)
1604 		return -1;
1605 	pos = info;
1606 	os_memcpy(pos, mac_init, ETH_ALEN);
1607 	pos += ETH_ALEN;
1608 	os_memcpy(pos, mac_resp, ETH_ALEN);
1609 	pos += ETH_ALEN;
1610 	os_memcpy(pos, Mx, Mx_len);
1611 	pos += Mx_len;
1612 	os_memcpy(pos, Nx, Nx_len);
1613 	pos += Nx_len;
1614 	os_memcpy(pos, code, os_strlen(code));
1615 
1616 	/* HKDF-Expand(PRK, info, L) */
1617 	if (hash_len == 32)
1618 		res = hmac_sha256_kdf(prk, hash_len, NULL, info, info_len,
1619 				      z, hash_len);
1620 	else if (hash_len == 48)
1621 		res = hmac_sha384_kdf(prk, hash_len, NULL, info, info_len,
1622 				      z, hash_len);
1623 	else if (hash_len == 64)
1624 		res = hmac_sha512_kdf(prk, hash_len, NULL, info, info_len,
1625 				      z, hash_len);
1626 	else
1627 		res = -1;
1628 	os_free(info);
1629 	os_memset(prk, 0, hash_len);
1630 	if (res < 0)
1631 		return -1;
1632 
1633 	wpa_hexdump_key(MSG_DEBUG, "DPP: z = HKDF-Expand(PRK, info, L)",
1634 			z, hash_len);
1635 	return 0;
1636 }
1637 
1638 
1639 int dpp_reconfig_derive_ke_responder(struct dpp_authentication *auth,
1640 				     const u8 *net_access_key,
1641 				     size_t net_access_key_len,
1642 				     struct json_token *peer_net_access_key)
1643 {
1644 	struct crypto_ec_key *own_key = NULL, *peer_key = NULL;
1645 	struct crypto_bignum *sum = NULL;
1646 	const struct crypto_bignum *q, *cR, *pR;
1647 	struct crypto_ec *ec = NULL;
1648 	struct crypto_ec_point *M = NULL;
1649 	const struct crypto_ec_point *CI;
1650 	u8 Mx[DPP_MAX_SHARED_SECRET_LEN];
1651 	u8 prk[DPP_MAX_HASH_LEN];
1652 	const struct dpp_curve_params *curve;
1653 	int res = -1;
1654 	u8 nonces[2 * DPP_MAX_NONCE_LEN];
1655 
1656 	own_key = dpp_set_keypair(&auth->curve, net_access_key,
1657 				  net_access_key_len);
1658 	if (!own_key) {
1659 		dpp_auth_fail(auth, "Failed to parse own netAccessKey");
1660 		goto fail;
1661 	}
1662 
1663 	peer_key = dpp_parse_jwk(peer_net_access_key, &curve);
1664 	if (!peer_key)
1665 		goto fail;
1666 	dpp_debug_print_key("DPP: Received netAccessKey", peer_key);
1667 
1668 	if (auth->curve != curve) {
1669 		wpa_printf(MSG_DEBUG,
1670 			   "DPP: Mismatching netAccessKey curves (own=%s != peer=%s)",
1671 			   auth->curve->name, curve->name);
1672 		goto fail;
1673 	}
1674 
1675 	auth->own_protocol_key = dpp_gen_keypair(curve);
1676 	if (!auth->own_protocol_key)
1677 		goto fail;
1678 
1679 	if (random_get_bytes(auth->e_nonce, auth->curve->nonce_len)) {
1680 		wpa_printf(MSG_ERROR, "DPP: Failed to generate E-nonce");
1681 		goto fail;
1682 	}
1683 	wpa_hexdump_key(MSG_DEBUG, "DPP: E-nonce",
1684 			auth->e_nonce, auth->curve->nonce_len);
1685 
1686 	/* M = { cR + pR } * CI */
1687 	ec = crypto_ec_init(curve->ike_group);
1688 	if (!ec)
1689 		goto fail;
1690 
1691 	sum = crypto_bignum_init();
1692 	q = crypto_ec_get_order(ec);
1693 	M = crypto_ec_point_init(ec);
1694 	cR = crypto_ec_key_get_private_key(own_key);
1695 	pR = crypto_ec_key_get_private_key(auth->own_protocol_key);
1696 	CI = crypto_ec_key_get_public_key(peer_key);
1697 	if (!sum || !q || !M || !cR || !pR || !CI ||
1698 	    crypto_bignum_addmod(cR, pR, q, sum) ||
1699 	    crypto_ec_point_mul(ec, CI, sum, M) ||
1700 	    crypto_ec_point_to_bin(ec, M, Mx, NULL)) {
1701 		wpa_printf(MSG_ERROR, "DPP: Error during M computation");
1702 		goto fail;
1703 	}
1704 	wpa_hexdump_key(MSG_DEBUG, "DPP: M.x", Mx, curve->prime_len);
1705 
1706 	/* ke = HKDF(C-nonce | E-nonce, "dpp reconfig key", M.x) */
1707 
1708 	/* HKDF-Extract(C-nonce | E-nonce, M.x) */
1709 	os_memcpy(nonces, auth->c_nonce, curve->nonce_len);
1710 	os_memcpy(&nonces[curve->nonce_len], auth->e_nonce, curve->nonce_len);
1711 	if (dpp_hmac(curve->hash_len, nonces, 2 * curve->nonce_len,
1712 		     Mx, curve->prime_len, prk) < 0)
1713 		goto fail;
1714 	wpa_hexdump_key(MSG_DEBUG, "DPP: PRK", prk, curve->hash_len);
1715 
1716 	/* HKDF-Expand(PRK, "dpp reconfig key", L) */
1717 	if (dpp_hkdf_expand(curve->hash_len, prk, curve->hash_len,
1718 			    "dpp reconfig key", auth->ke, curve->hash_len) < 0)
1719 		goto fail;
1720 	wpa_hexdump_key(MSG_DEBUG,
1721 			"DPP: ke = HKDF(C-nonce | E-nonce, \"dpp reconfig key\", M.x)",
1722 			auth->ke, curve->hash_len);
1723 
1724 	res = 0;
1725 	crypto_ec_key_deinit(auth->reconfig_old_protocol_key);
1726 	auth->reconfig_old_protocol_key = own_key;
1727 	own_key = NULL;
1728 fail:
1729 	forced_memzero(prk, sizeof(prk));
1730 	forced_memzero(Mx, sizeof(Mx));
1731 	crypto_ec_point_deinit(M, 1);
1732 	crypto_bignum_deinit(sum, 1);
1733 	crypto_ec_key_deinit(own_key);
1734 	crypto_ec_key_deinit(peer_key);
1735 	crypto_ec_deinit(ec);
1736 	return res;
1737 }
1738 
1739 
1740 int dpp_reconfig_derive_ke_initiator(struct dpp_authentication *auth,
1741 				     const u8 *r_proto, u16 r_proto_len,
1742 				     struct json_token *net_access_key)
1743 {
1744 	struct crypto_ec_key *pr = NULL, *peer_key = NULL;
1745 	const struct crypto_ec_point *CR, *PR;
1746 	const struct crypto_bignum *cI;
1747 	struct crypto_ec *ec = NULL;
1748 	struct crypto_ec_point *sum = NULL, *M = NULL;
1749 	u8 Mx[DPP_MAX_SHARED_SECRET_LEN];
1750 	u8 prk[DPP_MAX_HASH_LEN];
1751 	int res = -1;
1752 	const struct dpp_curve_params *curve;
1753 	u8 nonces[2 * DPP_MAX_NONCE_LEN];
1754 
1755 	pr = dpp_set_pubkey_point(auth->conf->connector_key,
1756 				  r_proto, r_proto_len);
1757 	if (!pr) {
1758 		dpp_auth_fail(auth, "Invalid Responder Protocol Key");
1759 		goto fail;
1760 	}
1761 	dpp_debug_print_key("Peer (Responder) Protocol Key", pr);
1762 	crypto_ec_key_deinit(auth->peer_protocol_key);
1763 	auth->peer_protocol_key = pr;
1764 	pr = NULL;
1765 
1766 	peer_key = dpp_parse_jwk(net_access_key, &curve);
1767 	if (!peer_key)
1768 		goto fail;
1769 	dpp_debug_print_key("DPP: Received netAccessKey", peer_key);
1770 	if (auth->curve != curve) {
1771 		wpa_printf(MSG_DEBUG,
1772 			   "DPP: Mismatching netAccessKey curves (own=%s != peer=%s)",
1773 			   auth->curve->name, curve->name);
1774 		goto fail;
1775 	}
1776 
1777 	/* M = cI * { CR + PR } */
1778 	ec = crypto_ec_init(curve->ike_group);
1779 	if (!ec)
1780 		goto fail;
1781 
1782 	cI = crypto_ec_key_get_private_key(auth->conf->connector_key);
1783 	sum = crypto_ec_point_init(ec);
1784 	M = crypto_ec_point_init(ec);
1785 	CR = crypto_ec_key_get_public_key(peer_key);
1786 	PR = crypto_ec_key_get_public_key(auth->peer_protocol_key);
1787 	if (!cI || !sum || !M || !CR || !PR ||
1788 	    crypto_ec_point_add(ec, CR, PR, sum) ||
1789 	    crypto_ec_point_mul(ec, sum, cI, M) ||
1790 	    crypto_ec_point_to_bin(ec, M, Mx, NULL)) {
1791 		wpa_printf(MSG_ERROR, "DPP: Error during M computation");
1792 		goto fail;
1793 	}
1794 
1795 	wpa_hexdump_key(MSG_DEBUG, "DPP: M.x", Mx, curve->prime_len);
1796 
1797 	/* ke = HKDF(C-nonce | E-nonce, "dpp reconfig key", M.x) */
1798 
1799 	/* HKDF-Extract(C-nonce | E-nonce, M.x) */
1800 	os_memcpy(nonces, auth->c_nonce, curve->nonce_len);
1801 	os_memcpy(&nonces[curve->nonce_len], auth->e_nonce, curve->nonce_len);
1802 	if (dpp_hmac(curve->hash_len, nonces, 2 * curve->nonce_len,
1803 		     Mx, curve->prime_len, prk) < 0)
1804 		goto fail;
1805 	wpa_hexdump_key(MSG_DEBUG, "DPP: PRK", prk, curve->hash_len);
1806 
1807 	/* HKDF-Expand(PRK, "dpp reconfig key", L) */
1808 	if (dpp_hkdf_expand(curve->hash_len, prk, curve->hash_len,
1809 			    "dpp reconfig key", auth->ke, curve->hash_len) < 0)
1810 		goto fail;
1811 	wpa_hexdump_key(MSG_DEBUG,
1812 			"DPP: ke = HKDF(C-nonce | E-nonce, \"dpp reconfig key\", M.x)",
1813 			auth->ke, curve->hash_len);
1814 
1815 	res = 0;
1816 fail:
1817 	forced_memzero(prk, sizeof(prk));
1818 	forced_memzero(Mx, sizeof(Mx));
1819 	crypto_ec_key_deinit(pr);
1820 	crypto_ec_key_deinit(peer_key);
1821 	crypto_ec_point_deinit(sum, 1);
1822 	crypto_ec_point_deinit(M, 1);
1823 	crypto_ec_deinit(ec);
1824 	return res;
1825 }
1826 
1827 
1828 static char *
1829 dpp_build_jws_prot_hdr(struct dpp_configurator *conf, size_t *signed1_len)
1830 {
1831 	struct wpabuf *jws_prot_hdr;
1832 	char *signed1;
1833 
1834 	jws_prot_hdr = wpabuf_alloc(100);
1835 	if (!jws_prot_hdr)
1836 		return NULL;
1837 	json_start_object(jws_prot_hdr, NULL);
1838 	json_add_string(jws_prot_hdr, "typ", "dppCon");
1839 	json_value_sep(jws_prot_hdr);
1840 	json_add_string(jws_prot_hdr, "kid", conf->kid);
1841 	json_value_sep(jws_prot_hdr);
1842 	json_add_string(jws_prot_hdr, "alg", conf->curve->jws_alg);
1843 	json_end_object(jws_prot_hdr);
1844 	signed1 = base64_url_encode(wpabuf_head(jws_prot_hdr),
1845 				    wpabuf_len(jws_prot_hdr),
1846 				    signed1_len);
1847 	wpabuf_free(jws_prot_hdr);
1848 	return signed1;
1849 }
1850 
1851 
1852 static char *
1853 dpp_build_conn_signature(struct dpp_configurator *conf,
1854 			 const char *signed1, size_t signed1_len,
1855 			 const char *signed2, size_t signed2_len,
1856 			 size_t *signed3_len)
1857 {
1858 	const struct dpp_curve_params *curve;
1859 	struct wpabuf *sig = NULL;
1860 	char *signed3 = NULL;
1861 	char *dot = ".";
1862 	const u8 *vector[3];
1863 	size_t vector_len[3];
1864 	u8 *hash;
1865 	int ret;
1866 
1867 	vector[0] = (const u8 *) signed1;
1868 	vector[1] = (const u8 *) dot;
1869 	vector[2] = (const u8 *) signed2;
1870 	vector_len[0] = signed1_len;
1871 	vector_len[1] = 1;
1872 	vector_len[2] = signed2_len;
1873 
1874 	curve = conf->curve;
1875 	hash = os_malloc(curve->hash_len);
1876 	if (!hash)
1877 		goto fail;
1878 	if (curve->hash_len == SHA256_MAC_LEN) {
1879 		ret = sha256_vector(3, vector, vector_len, hash);
1880 	} else if (curve->hash_len == SHA384_MAC_LEN) {
1881 		ret = sha384_vector(3, vector, vector_len, hash);
1882 	} else if (curve->hash_len == SHA512_MAC_LEN) {
1883 		ret = sha512_vector(3, vector, vector_len, hash);
1884 	} else {
1885 		wpa_printf(MSG_DEBUG, "DPP: Unknown signature algorithm");
1886 		goto fail;
1887 	}
1888 	if (ret) {
1889 		wpa_printf(MSG_DEBUG, "DPP: Hash computation failed");
1890 		goto fail;
1891 	}
1892 	wpa_hexdump(MSG_DEBUG, "DPP: Hash value for Connector signature",
1893 		    hash, curve->hash_len);
1894 
1895 	sig = crypto_ec_key_sign_r_s(conf->csign, hash, curve->hash_len);
1896 	if (!sig) {
1897 		wpa_printf(MSG_ERROR, "DPP: Signature computation failed");
1898 		goto fail;
1899 	}
1900 
1901 	wpa_hexdump(MSG_DEBUG, "DPP: signedConnector ECDSA signature (raw r,s)",
1902 		    wpabuf_head(sig), wpabuf_len(sig));
1903 	signed3 = base64_url_encode(wpabuf_head(sig), wpabuf_len(sig),
1904 				    signed3_len);
1905 
1906 fail:
1907 	os_free(hash);
1908 	wpabuf_free(sig);
1909 	return signed3;
1910 }
1911 
1912 char * dpp_sign_connector(struct dpp_configurator *conf,
1913 			  const struct wpabuf *dppcon)
1914 {
1915 	char *signed1 = NULL, *signed2 = NULL, *signed3 = NULL;
1916 	char *signed_conn = NULL, *pos;
1917 	size_t signed1_len, signed2_len, signed3_len;
1918 
1919 	signed1 = dpp_build_jws_prot_hdr(conf, &signed1_len);
1920 	signed2 = base64_url_encode(wpabuf_head(dppcon), wpabuf_len(dppcon),
1921 				    &signed2_len);
1922 	if (!signed1 || !signed2)
1923 		goto fail;
1924 
1925 	signed3 = dpp_build_conn_signature(conf, signed1, signed1_len,
1926 					   signed2, signed2_len, &signed3_len);
1927 	if (!signed3)
1928 		goto fail;
1929 
1930 	signed_conn = os_malloc(signed1_len + signed2_len + signed3_len + 3);
1931 	if (!signed_conn)
1932 		goto fail;
1933 	pos = signed_conn;
1934 	os_memcpy(pos, signed1, signed1_len);
1935 	pos += signed1_len;
1936 	*pos++ = '.';
1937 	os_memcpy(pos, signed2, signed2_len);
1938 	pos += signed2_len;
1939 	*pos++ = '.';
1940 	os_memcpy(pos, signed3, signed3_len);
1941 	pos += signed3_len;
1942 	*pos = '\0';
1943 
1944 fail:
1945 	os_free(signed1);
1946 	os_free(signed2);
1947 	os_free(signed3);
1948 	return signed_conn;
1949 }
1950 
1951 
1952 #ifdef CONFIG_DPP2
1953 
1954 struct dpp_pfs * dpp_pfs_init(const u8 *net_access_key,
1955 			      size_t net_access_key_len)
1956 {
1957 	struct wpabuf *pub = NULL;
1958 	struct crypto_ec_key *own_key;
1959 	struct dpp_pfs *pfs;
1960 
1961 	pfs = os_zalloc(sizeof(*pfs));
1962 	if (!pfs)
1963 		return NULL;
1964 
1965 	own_key = dpp_set_keypair(&pfs->curve, net_access_key,
1966 				  net_access_key_len);
1967 	if (!own_key) {
1968 		wpa_printf(MSG_ERROR, "DPP: Failed to parse own netAccessKey");
1969 		goto fail;
1970 	}
1971 	crypto_ec_key_deinit(own_key);
1972 
1973 	pfs->ecdh = crypto_ecdh_init(pfs->curve->ike_group);
1974 	if (!pfs->ecdh)
1975 		goto fail;
1976 
1977 	pub = crypto_ecdh_get_pubkey(pfs->ecdh, 0);
1978 	pub = wpabuf_zeropad(pub, pfs->curve->prime_len);
1979 	if (!pub)
1980 		goto fail;
1981 
1982 	pfs->ie = wpabuf_alloc(5 + wpabuf_len(pub));
1983 	if (!pfs->ie)
1984 		goto fail;
1985 	wpabuf_put_u8(pfs->ie, WLAN_EID_EXTENSION);
1986 	wpabuf_put_u8(pfs->ie, 1 + 2 + wpabuf_len(pub));
1987 	wpabuf_put_u8(pfs->ie, WLAN_EID_EXT_OWE_DH_PARAM);
1988 	wpabuf_put_le16(pfs->ie, pfs->curve->ike_group);
1989 	wpabuf_put_buf(pfs->ie, pub);
1990 	wpabuf_free(pub);
1991 	wpa_hexdump_buf(MSG_DEBUG, "DPP: Diffie-Hellman Parameter element",
1992 			pfs->ie);
1993 
1994 	return pfs;
1995 fail:
1996 	wpabuf_free(pub);
1997 	dpp_pfs_free(pfs);
1998 	return NULL;
1999 }
2000 
2001 
2002 int dpp_pfs_process(struct dpp_pfs *pfs, const u8 *peer_ie, size_t peer_ie_len)
2003 {
2004 	if (peer_ie_len < 2)
2005 		return -1;
2006 	if (WPA_GET_LE16(peer_ie) != pfs->curve->ike_group) {
2007 		wpa_printf(MSG_DEBUG, "DPP: Peer used different group for PFS");
2008 		return -1;
2009 	}
2010 
2011 	pfs->secret = crypto_ecdh_set_peerkey(pfs->ecdh, 0, peer_ie + 2,
2012 					      peer_ie_len - 2);
2013 	pfs->secret = wpabuf_zeropad(pfs->secret, pfs->curve->prime_len);
2014 	if (!pfs->secret) {
2015 		wpa_printf(MSG_DEBUG, "DPP: Invalid peer DH public key");
2016 		return -1;
2017 	}
2018 	wpa_hexdump_buf_key(MSG_DEBUG, "DPP: DH shared secret", pfs->secret);
2019 	return 0;
2020 }
2021 
2022 
2023 void dpp_pfs_free(struct dpp_pfs *pfs)
2024 {
2025 	if (!pfs)
2026 		return;
2027 	crypto_ecdh_deinit(pfs->ecdh);
2028 	wpabuf_free(pfs->ie);
2029 	wpabuf_clear_free(pfs->secret);
2030 	os_free(pfs);
2031 }
2032 
2033 
2034 struct wpabuf * dpp_build_csr(struct dpp_authentication *auth, const char *name)
2035 {
2036 	struct crypto_csr *csr = NULL;
2037 	struct wpabuf *buf = NULL;
2038 	struct crypto_ec_key *key;
2039 	unsigned int hash_len = auth->curve->hash_len;
2040 	struct wpabuf *priv_key;
2041 	u8 cp[DPP_CP_LEN];
2042 	char *password = NULL;
2043 	size_t password_len;
2044 	int hash_sign_algo;
2045 
2046 	/* TODO: use auth->csrattrs */
2047 
2048 	/* TODO: support generation of a new private key if csrAttrs requests
2049 	 * a specific group to be used */
2050 	key = auth->own_protocol_key;
2051 
2052 	priv_key = crypto_ec_key_get_ecprivate_key(key, true);
2053 	if (!priv_key)
2054 		goto fail;
2055 	wpabuf_free(auth->priv_key);
2056 	auth->priv_key = priv_key;
2057 
2058 	csr = crypto_csr_init();
2059 	if (!csr || crypto_csr_set_ec_public_key(csr, key))
2060 		goto fail;
2061 
2062 	if (name && crypto_csr_set_name(csr, CSR_NAME_CN, name))
2063 		goto fail;
2064 
2065 	/* cp = HKDF-Expand(bk, "CSR challengePassword", 64) */
2066 	if (dpp_hkdf_expand(hash_len, auth->bk, hash_len,
2067 			    "CSR challengePassword", cp, DPP_CP_LEN) < 0)
2068 		goto fail;
2069 	wpa_hexdump_key(MSG_DEBUG,
2070 			"DPP: cp = HKDF-Expand(bk, \"CSR challengePassword\", 64)",
2071 			cp, DPP_CP_LEN);
2072 	password = base64_encode_no_lf(cp, DPP_CP_LEN, &password_len);
2073 	forced_memzero(cp, DPP_CP_LEN);
2074 	if (!password ||
2075 	    crypto_csr_set_attribute(csr, CSR_ATTR_CHALLENGE_PASSWORD,
2076 				     ASN1_TAG_UTF8STRING, (const u8 *) password,
2077 				     password_len))
2078 		goto fail;
2079 
2080 	/* TODO: hash func selection based on csrAttrs */
2081 	if (hash_len == SHA256_MAC_LEN) {
2082 		hash_sign_algo = CRYPTO_HASH_ALG_SHA256;
2083 	} else if (hash_len == SHA384_MAC_LEN) {
2084 		hash_sign_algo = CRYPTO_HASH_ALG_SHA384;
2085 	} else if (hash_len == SHA512_MAC_LEN) {
2086 		hash_sign_algo = CRYPTO_HASH_ALG_SHA512;
2087 	} else {
2088 		wpa_printf(MSG_DEBUG, "DPP: Unknown signature algorithm");
2089 		goto fail;
2090 	}
2091 
2092 	buf = crypto_csr_sign(csr, key, hash_sign_algo);
2093 	if (!buf)
2094 		goto fail;
2095 	wpa_hexdump_buf(MSG_DEBUG, "DPP: CSR", buf);
2096 
2097 fail:
2098 	bin_clear_free(password, password_len);
2099 	crypto_csr_deinit(csr);
2100 	return buf;
2101 }
2102 
2103 
2104 int dpp_validate_csr(struct dpp_authentication *auth,
2105 		     const struct wpabuf *csrbuf)
2106 {
2107 	struct crypto_csr *csr;
2108 	const u8 *attr;
2109 	size_t attr_len;
2110 	int attr_type;
2111 	unsigned char *cp = NULL;
2112 	size_t cp_len;
2113 	u8 exp_cp[DPP_CP_LEN];
2114 	unsigned int hash_len = auth->curve->hash_len;
2115 	int ret = -1;
2116 
2117 	csr = crypto_csr_verify(csrbuf);
2118 	if (!csr) {
2119 		wpa_printf(MSG_DEBUG,
2120 			   "DPP: CSR invalid or invalid signature");
2121 		goto fail;
2122 	}
2123 
2124 	attr = crypto_csr_get_attribute(csr, CSR_ATTR_CHALLENGE_PASSWORD,
2125 					&attr_len, &attr_type);
2126 	if (!attr) {
2127 		wpa_printf(MSG_DEBUG,
2128 			   "DPP: CSR does not include challengePassword");
2129 		goto fail;
2130 	}
2131 	/* This is supposed to be UTF8String, but allow other strings as well
2132 	 * since challengePassword is using ASCII (base64 encoded). */
2133 	if (attr_type != ASN1_TAG_UTF8STRING &&
2134 	    attr_type != ASN1_TAG_PRINTABLESTRING &&
2135 	    attr_type != ASN1_TAG_IA5STRING) {
2136 		wpa_printf(MSG_DEBUG,
2137 			   "DPP: Unexpected challengePassword attribute type %d",
2138 			   attr_type);
2139 		goto fail;
2140 	}
2141 
2142 	cp = base64_decode((const char *) attr, attr_len, &cp_len);
2143 	if (!cp) {
2144 		wpa_printf(MSG_DEBUG,
2145 			   "DPP: Could not base64 decode challengePassword");
2146 		goto fail;
2147 	}
2148 	if (cp_len != DPP_CP_LEN) {
2149 		wpa_printf(MSG_DEBUG,
2150 			   "DPP: Unexpected cp length (%zu) in CSR challengePassword",
2151 			   cp_len);
2152 		goto fail;
2153 	}
2154 	wpa_hexdump_key(MSG_DEBUG, "DPP: cp from CSR challengePassword",
2155 			cp, cp_len);
2156 
2157 	/* cp = HKDF-Expand(bk, "CSR challengePassword", 64) */
2158 	if (dpp_hkdf_expand(hash_len, auth->bk, hash_len,
2159 			    "CSR challengePassword", exp_cp, DPP_CP_LEN) < 0)
2160 		goto fail;
2161 	wpa_hexdump_key(MSG_DEBUG,
2162 			"DPP: cp = HKDF-Expand(bk, \"CSR challengePassword\", 64)",
2163 			exp_cp, DPP_CP_LEN);
2164 	if (os_memcmp_const(cp, exp_cp, DPP_CP_LEN) != 0) {
2165 		wpa_printf(MSG_DEBUG,
2166 			   "DPP: CSR challengePassword does not match calculated cp");
2167 		goto fail;
2168 	}
2169 
2170 	ret = 0;
2171 fail:
2172 	os_free(cp);
2173 	crypto_csr_deinit(csr);
2174 	return ret;
2175 }
2176 
2177 
2178 struct dpp_reconfig_id * dpp_gen_reconfig_id(const u8 *csign_key,
2179 					     size_t csign_key_len,
2180 					     const u8 *pp_key,
2181 					     size_t pp_key_len)
2182 {
2183 	struct crypto_ec_key *csign = NULL, *ppkey = NULL;
2184 	struct dpp_reconfig_id *id = NULL;
2185 	struct crypto_ec *ec = NULL;
2186 	const struct crypto_bignum *q;
2187 	struct crypto_bignum *bn = NULL;
2188 	struct crypto_ec_point *e_id = NULL;
2189 	const struct crypto_ec_point *generator;
2190 
2191 	csign = crypto_ec_key_parse_pub(csign_key, csign_key_len);
2192 	if (!csign)
2193 		goto fail;
2194 
2195 	if (!pp_key)
2196 		goto fail;
2197 	ppkey = crypto_ec_key_parse_pub(pp_key, pp_key_len);
2198 	if (!ppkey)
2199 		goto fail;
2200 
2201 	ec = crypto_ec_init(crypto_ec_key_group(csign));
2202 	if (!ec)
2203 		goto fail;
2204 
2205 	e_id = crypto_ec_point_init(ec);
2206 	bn = crypto_bignum_init();
2207 	q = crypto_ec_get_order(ec);
2208 	generator = crypto_ec_get_generator(ec);
2209 	if (!e_id || !bn || !q || !generator ||
2210 	    crypto_bignum_rand(bn, q) ||
2211 	    crypto_ec_point_mul(ec, generator, bn, e_id))
2212 		goto fail;
2213 
2214 	crypto_ec_point_debug_print(ec, e_id,
2215 				    "DPP: Generated random point E-id");
2216 
2217 	id = os_zalloc(sizeof(*id));
2218 	if (!id)
2219 		goto fail;
2220 
2221 	id->ec = ec;
2222 	ec = NULL;
2223 	id->e_id = e_id;
2224 	e_id = NULL;
2225 	id->csign = csign;
2226 	csign = NULL;
2227 	id->pp_key = ppkey;
2228 	ppkey = NULL;
2229 fail:
2230 	crypto_ec_point_deinit(e_id, 1);
2231 	crypto_ec_key_deinit(csign);
2232 	crypto_ec_key_deinit(ppkey);
2233 	crypto_bignum_deinit(bn, 1);
2234 	crypto_ec_deinit(ec);
2235 	return id;
2236 }
2237 
2238 
2239 int dpp_update_reconfig_id(struct dpp_reconfig_id *id)
2240 {
2241 	const struct crypto_bignum *q;
2242 	struct crypto_bignum *bn;
2243 	const struct crypto_ec_point *pp, *generator;
2244 	struct crypto_ec_point *e_prime_id, *a_nonce;
2245 	int ret = -1;
2246 
2247 	pp = crypto_ec_key_get_public_key(id->pp_key);
2248 	e_prime_id = crypto_ec_point_init(id->ec);
2249 	a_nonce = crypto_ec_point_init(id->ec);
2250 	bn = crypto_bignum_init();
2251 	q = crypto_ec_get_order(id->ec);
2252 	generator = crypto_ec_get_generator(id->ec);
2253 
2254 	/* Generate random 0 <= a-nonce < q
2255 	 * A-NONCE = a-nonce * G
2256 	 * E'-id = E-id + a-nonce * P_pk */
2257 	if (!pp || !e_prime_id || !a_nonce || !bn || !q || !generator ||
2258 	    crypto_bignum_rand(bn, q) || /* bn = a-nonce */
2259 	    crypto_ec_point_mul(id->ec, generator, bn, a_nonce) ||
2260 	    crypto_ec_point_mul(id->ec, pp, bn, e_prime_id) ||
2261 	    crypto_ec_point_add(id->ec, id->e_id, e_prime_id, e_prime_id))
2262 		goto fail;
2263 
2264 	crypto_ec_point_debug_print(id->ec, a_nonce,
2265 				    "DPP: Generated A-NONCE");
2266 	crypto_ec_point_debug_print(id->ec, e_prime_id,
2267 				    "DPP: Encrypted E-id to E'-id");
2268 
2269 	crypto_ec_key_deinit(id->a_nonce);
2270 	crypto_ec_key_deinit(id->e_prime_id);
2271 	id->a_nonce = crypto_ec_key_set_pub_point(id->ec, a_nonce);
2272 	id->e_prime_id = crypto_ec_key_set_pub_point(id->ec, e_prime_id);
2273 	if (!id->a_nonce || !id->e_prime_id)
2274 		goto fail;
2275 
2276 	ret = 0;
2277 
2278 fail:
2279 	crypto_ec_point_deinit(e_prime_id, 1);
2280 	crypto_ec_point_deinit(a_nonce, 1);
2281 	crypto_bignum_deinit(bn, 1);
2282 	return ret;
2283 }
2284 
2285 
2286 void dpp_free_reconfig_id(struct dpp_reconfig_id *id)
2287 {
2288 	if (id) {
2289 		crypto_ec_point_deinit(id->e_id, 1);
2290 		crypto_ec_key_deinit(id->csign);
2291 		crypto_ec_key_deinit(id->a_nonce);
2292 		crypto_ec_key_deinit(id->e_prime_id);
2293 		crypto_ec_key_deinit(id->pp_key);
2294 		crypto_ec_deinit(id->ec);
2295 		os_free(id);
2296 	}
2297 }
2298 
2299 
2300 struct crypto_ec_point * dpp_decrypt_e_id(struct crypto_ec_key *ppkey,
2301 					  struct crypto_ec_key *a_nonce,
2302 					  struct crypto_ec_key *e_prime_id)
2303 {
2304 	struct crypto_ec *ec;
2305 	const struct crypto_bignum *pp;
2306 	struct crypto_ec_point *e_id = NULL;
2307 	const struct crypto_ec_point *a_nonce_point, *e_prime_id_point;
2308 
2309 	if (!ppkey)
2310 		return NULL;
2311 
2312 	/* E-id = E'-id - s_C * A-NONCE */
2313 	ec = crypto_ec_init(crypto_ec_key_group(ppkey));
2314 	if (!ec)
2315 		return NULL;
2316 
2317 	pp = crypto_ec_key_get_private_key(ppkey);
2318 	a_nonce_point = crypto_ec_key_get_public_key(a_nonce);
2319 	e_prime_id_point = crypto_ec_key_get_public_key(e_prime_id);
2320 	e_id = crypto_ec_point_init(ec);
2321 	if (!pp || !a_nonce_point || !e_prime_id_point || !e_id ||
2322 	    crypto_ec_point_mul(ec, a_nonce_point, pp, e_id) ||
2323 	    crypto_ec_point_invert(ec, e_id) ||
2324 	    crypto_ec_point_add(ec, e_id, e_prime_id_point, e_id)) {
2325 		crypto_ec_point_deinit(e_id, 1);
2326 		goto fail;
2327 	}
2328 
2329 	crypto_ec_point_debug_print(ec, e_id, "DPP: Decrypted E-id");
2330 
2331 fail:
2332 	crypto_ec_deinit(ec);
2333 	return e_id;
2334 }
2335 
2336 #endif /* CONFIG_DPP2 */
2337 
2338 
2339 #ifdef CONFIG_TESTING_OPTIONS
2340 
2341 int dpp_test_gen_invalid_key(struct wpabuf *msg,
2342 			     const struct dpp_curve_params *curve)
2343 {
2344 	struct crypto_ec *ec;
2345 	struct crypto_ec_key *key = NULL;
2346 	const struct crypto_ec_point *pub_key;
2347 	struct crypto_ec_point *p = NULL;
2348 	u8 *x, *y;
2349 	int ret = -1;
2350 
2351 	ec = crypto_ec_init(curve->ike_group);
2352 	x = wpabuf_put(msg, curve->prime_len);
2353 	y = wpabuf_put(msg, curve->prime_len);
2354 	if (!ec)
2355 		goto fail;
2356 
2357 retry:
2358 	/* Generate valid key pair */
2359 	key = crypto_ec_key_gen(curve->ike_group);
2360 	if (!key)
2361 		goto fail;
2362 
2363 	/* Retrieve public key coordinates */
2364 	pub_key = crypto_ec_key_get_public_key(key);
2365 	if (!pub_key)
2366 		goto fail;
2367 
2368 	crypto_ec_point_to_bin(ec, pub_key, x, y);
2369 
2370 	/* And corrupt them */
2371 	y[curve->prime_len - 1] ^= 0x01;
2372 	p = crypto_ec_point_from_bin(ec, x);
2373 	if (p && crypto_ec_point_is_on_curve(ec, p)) {
2374 		crypto_ec_point_deinit(p, 0);
2375 		p = NULL;
2376 		goto retry;
2377 	}
2378 
2379 	ret = 0;
2380 fail:
2381 	crypto_ec_point_deinit(p, 0);
2382 	crypto_ec_key_deinit(key);
2383 	crypto_ec_deinit(ec);
2384 	return ret;
2385 }
2386 
2387 
2388 char * dpp_corrupt_connector_signature(const char *connector)
2389 {
2390 	char *tmp, *pos, *signed3 = NULL;
2391 	unsigned char *signature = NULL;
2392 	size_t signature_len = 0, signed3_len;
2393 
2394 	tmp = os_zalloc(os_strlen(connector) + 5);
2395 	if (!tmp)
2396 		goto fail;
2397 	os_memcpy(tmp, connector, os_strlen(connector));
2398 
2399 	pos = os_strchr(tmp, '.');
2400 	if (!pos)
2401 		goto fail;
2402 
2403 	pos = os_strchr(pos + 1, '.');
2404 	if (!pos)
2405 		goto fail;
2406 	pos++;
2407 
2408 	wpa_printf(MSG_DEBUG, "DPP: Original base64url encoded signature: %s",
2409 		   pos);
2410 	signature = base64_url_decode(pos, os_strlen(pos), &signature_len);
2411 	if (!signature || signature_len == 0)
2412 		goto fail;
2413 	wpa_hexdump(MSG_DEBUG, "DPP: Original Connector signature",
2414 		    signature, signature_len);
2415 	signature[signature_len - 1] ^= 0x01;
2416 	wpa_hexdump(MSG_DEBUG, "DPP: Corrupted Connector signature",
2417 		    signature, signature_len);
2418 	signed3 = base64_url_encode(signature, signature_len, &signed3_len);
2419 	if (!signed3)
2420 		goto fail;
2421 	os_memcpy(pos, signed3, signed3_len);
2422 	pos[signed3_len] = '\0';
2423 	wpa_printf(MSG_DEBUG, "DPP: Corrupted base64url encoded signature: %s",
2424 		   pos);
2425 
2426 out:
2427 	os_free(signature);
2428 	os_free(signed3);
2429 	return tmp;
2430 fail:
2431 	os_free(tmp);
2432 	tmp = NULL;
2433 	goto out;
2434 }
2435 
2436 #endif /* CONFIG_TESTING_OPTIONS */
2437