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