xref: /freebsd/contrib/wpa/src/common/dpp_crypto.c (revision 32a95656)
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_gen_keypair(const struct dpp_curve_params * curve)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 
dpp_set_keypair(const struct dpp_curve_params ** curve,const u8 * privkey,size_t privkey_len)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 
dpp_bootstrap_key_hash(struct dpp_bootstrap_info * bi)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 
dpp_keygen(struct dpp_bootstrap_info * bi,const char * curve,const u8 * privkey,size_t privkey_len)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 
dpp_derive_k1(const u8 * Mx,size_t Mx_len,u8 * k1,unsigned int hash_len)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 
dpp_derive_k2(const u8 * Nx,size_t Nx_len,u8 * k2,unsigned int hash_len)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 
dpp_derive_bk_ke(struct dpp_authentication * auth)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 
dpp_ecdh(struct crypto_ec_key * own,struct crypto_ec_key * peer,u8 * secret,size_t * secret_len)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 
dpp_bi_pubkey_hash(struct dpp_bootstrap_info * bi,const u8 * data,size_t data_len)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 
dpp_get_subject_public_key(struct dpp_bootstrap_info * bi,const u8 * data,size_t data_len)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 *
dpp_parse_jws_prot_hdr(const struct dpp_curve_params * curve,const u8 * prot_hdr,u16 prot_hdr_len,int * hash_func)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 
dpp_check_pubkey_match(struct crypto_ec_key * pub,struct wpabuf * r_hash)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
dpp_process_signed_connector(struct dpp_signed_connector_info * info,struct crypto_ec_key * csign_pub,const char * connector)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
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)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 
dpp_gen_r_auth(struct dpp_authentication * auth,u8 * r_auth)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 
dpp_gen_i_auth(struct dpp_authentication * auth,u8 * i_auth)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 
dpp_auth_derive_l_responder(struct dpp_authentication * auth)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 
dpp_auth_derive_l_initiator(struct dpp_authentication * auth)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 
dpp_derive_pmk(const u8 * Nx,size_t Nx_len,u8 * pmk,unsigned int hash_len)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 
dpp_derive_pmkid(const struct dpp_curve_params * curve,struct crypto_ec_key * own_key,struct crypto_ec_key * peer_key,u8 * pmkid)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 *
dpp_pkex_get_role_elem(const struct dpp_curve_params * curve,int init)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 *
dpp_pkex_derive_Qi(const struct dpp_curve_params * curve,const u8 * mac_init,const char * code,const char * identifier,struct crypto_ec ** ret_ec)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 	if (mac_init) {
1453 		wpa_printf(MSG_DEBUG, "DPP: MAC-Initiator: " MACSTR,
1454 			   MAC2STR(mac_init));
1455 		addr[num_elem] = mac_init;
1456 		len[num_elem] = ETH_ALEN;
1457 		num_elem++;
1458 	}
1459 	if (identifier) {
1460 		wpa_printf(MSG_DEBUG, "DPP: code identifier: %s",
1461 			   identifier);
1462 		addr[num_elem] = (const u8 *) identifier;
1463 		len[num_elem] = os_strlen(identifier);
1464 		num_elem++;
1465 	}
1466 	wpa_hexdump_ascii_key(MSG_DEBUG, "DPP: code", code, os_strlen(code));
1467 	addr[num_elem] = (const u8 *) code;
1468 	len[num_elem] = os_strlen(code);
1469 	num_elem++;
1470 	if (dpp_hash_vector(curve, num_elem, addr, len, hash) < 0)
1471 		goto fail;
1472 	wpa_hexdump_key(MSG_DEBUG,
1473 			"DPP: H([MAC-Initiator |] [identifier |] code)",
1474 			hash, curve->hash_len);
1475 	Pi_key = dpp_pkex_get_role_elem(curve, 1);
1476 	if (!Pi_key)
1477 		goto fail;
1478 	dpp_debug_print_key("DPP: Pi", Pi_key);
1479 
1480 	ec = crypto_ec_init(curve->ike_group);
1481 	if (!ec)
1482 		goto fail;
1483 
1484 	Pi = crypto_ec_key_get_public_key(Pi_key);
1485 	Qi = crypto_ec_point_init(ec);
1486 	hash_bn = crypto_bignum_init_set(hash, curve->hash_len);
1487 	if (!Pi || !Qi || !hash_bn || crypto_ec_point_mul(ec, Pi, hash_bn, Qi))
1488 		goto fail;
1489 
1490 	if (crypto_ec_point_is_at_infinity(ec, Qi)) {
1491 		wpa_printf(MSG_INFO, "DPP: Qi is the point-at-infinity");
1492 		goto fail;
1493 	}
1494 	crypto_ec_point_debug_print(ec, Qi, "DPP: Qi");
1495 out:
1496 	crypto_ec_key_deinit(Pi_key);
1497 	crypto_bignum_deinit(hash_bn, 1);
1498 	if (ret_ec && Qi)
1499 		*ret_ec = ec;
1500 	else
1501 		crypto_ec_deinit(ec);
1502 	return Qi;
1503 fail:
1504 	crypto_ec_point_deinit(Qi, 1);
1505 	Qi = NULL;
1506 	goto out;
1507 }
1508 
1509 
1510 struct crypto_ec_point *
dpp_pkex_derive_Qr(const struct dpp_curve_params * curve,const u8 * mac_resp,const char * code,const char * identifier,struct crypto_ec ** ret_ec)1511 dpp_pkex_derive_Qr(const struct dpp_curve_params *curve, const u8 *mac_resp,
1512 		   const char *code, const char *identifier,
1513 		   struct crypto_ec **ret_ec)
1514 {
1515 	u8 hash[DPP_MAX_HASH_LEN];
1516 	const u8 *addr[3];
1517 	size_t len[3];
1518 	unsigned int num_elem = 0;
1519 	struct crypto_ec_point *Qr = NULL;
1520 	struct crypto_ec_key *Pr_key = NULL;
1521 	const struct crypto_ec_point *Pr = NULL;
1522 	struct crypto_bignum *hash_bn = NULL;
1523 	struct crypto_ec *ec = NULL;
1524 
1525 	/* Qr = H([MAC-Responder |] [identifier |] code) * Pr */
1526 
1527 	if (mac_resp) {
1528 		wpa_printf(MSG_DEBUG, "DPP: MAC-Responder: " MACSTR,
1529 			   MAC2STR(mac_resp));
1530 		addr[num_elem] = mac_resp;
1531 		len[num_elem] = ETH_ALEN;
1532 		num_elem++;
1533 	}
1534 	if (identifier) {
1535 		wpa_printf(MSG_DEBUG, "DPP: code identifier: %s",
1536 			   identifier);
1537 		addr[num_elem] = (const u8 *) identifier;
1538 		len[num_elem] = os_strlen(identifier);
1539 		num_elem++;
1540 	}
1541 	wpa_hexdump_ascii_key(MSG_DEBUG, "DPP: code", code, os_strlen(code));
1542 	addr[num_elem] = (const u8 *) code;
1543 	len[num_elem] = os_strlen(code);
1544 	num_elem++;
1545 	if (dpp_hash_vector(curve, num_elem, addr, len, hash) < 0)
1546 		goto fail;
1547 	wpa_hexdump_key(MSG_DEBUG,
1548 			"DPP: H([MAC-Responder |] [identifier |] code)",
1549 			hash, curve->hash_len);
1550 	Pr_key = dpp_pkex_get_role_elem(curve, 0);
1551 	if (!Pr_key)
1552 		goto fail;
1553 	dpp_debug_print_key("DPP: Pr", Pr_key);
1554 
1555 	ec = crypto_ec_init(curve->ike_group);
1556 	if (!ec)
1557 		goto fail;
1558 
1559 	Pr = crypto_ec_key_get_public_key(Pr_key);
1560 	Qr = crypto_ec_point_init(ec);
1561 	hash_bn = crypto_bignum_init_set(hash, curve->hash_len);
1562 	if (!Pr || !Qr || !hash_bn || crypto_ec_point_mul(ec, Pr, hash_bn, Qr))
1563 		goto fail;
1564 
1565 	if (crypto_ec_point_is_at_infinity(ec, Qr)) {
1566 		wpa_printf(MSG_INFO, "DPP: Qr is the point-at-infinity");
1567 		goto fail;
1568 	}
1569 	crypto_ec_point_debug_print(ec, Qr, "DPP: Qr");
1570 
1571 out:
1572 	crypto_ec_key_deinit(Pr_key);
1573 	crypto_bignum_deinit(hash_bn, 1);
1574 	if (ret_ec && Qr)
1575 		*ret_ec = ec;
1576 	else
1577 		crypto_ec_deinit(ec);
1578 	return Qr;
1579 fail:
1580 	crypto_ec_point_deinit(Qr, 1);
1581 	Qr = NULL;
1582 	goto out;
1583 }
1584 
1585 
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,const u8 * Kx,size_t Kx_len,u8 * z,unsigned int hash_len)1586 int dpp_pkex_derive_z(const u8 *mac_init, const u8 *mac_resp,
1587 		      u8 ver_init, u8 ver_resp,
1588 		      const u8 *Mx, size_t Mx_len,
1589 		      const u8 *Nx, size_t Nx_len,
1590 		      const char *code,
1591 		      const u8 *Kx, size_t Kx_len,
1592 		      u8 *z, unsigned int hash_len)
1593 {
1594 	u8 salt[DPP_MAX_HASH_LEN], prk[DPP_MAX_HASH_LEN];
1595 	int res;
1596 	u8 *info, *pos;
1597 	size_t info_len;
1598 
1599 	/*
1600 	 * v1: info = MAC-Initiator | MAC-Responder
1601 	 * v2: info = Protocol Version-Initiator | Protocol Version-Responder
1602 	 * z = HKDF(<>, info | M.x | N.x | code, K.x)
1603 	 */
1604 
1605 	/* HKDF-Extract(<>, IKM=K.x) */
1606 	os_memset(salt, 0, hash_len);
1607 	if (dpp_hmac(hash_len, salt, hash_len, Kx, Kx_len, prk) < 0)
1608 		return -1;
1609 	wpa_hexdump_key(MSG_DEBUG, "DPP: PRK = HKDF-Extract(<>, IKM)",
1610 			prk, hash_len);
1611 	if (mac_init && mac_resp)
1612 		info_len = 2 * ETH_ALEN;
1613 	else
1614 		info_len = 2;
1615 	info_len += Mx_len + Nx_len + os_strlen(code);
1616 	info = os_malloc(info_len);
1617 	if (!info)
1618 		return -1;
1619 	pos = info;
1620 	if (mac_init && mac_resp) {
1621 		os_memcpy(pos, mac_init, ETH_ALEN);
1622 		pos += ETH_ALEN;
1623 		os_memcpy(pos, mac_resp, ETH_ALEN);
1624 		pos += ETH_ALEN;
1625 	} else {
1626 		*pos++ = ver_init;
1627 		*pos++ = ver_resp;
1628 	}
1629 	os_memcpy(pos, Mx, Mx_len);
1630 	pos += Mx_len;
1631 	os_memcpy(pos, Nx, Nx_len);
1632 	pos += Nx_len;
1633 	os_memcpy(pos, code, os_strlen(code));
1634 
1635 	/* HKDF-Expand(PRK, info, L) */
1636 	if (hash_len == 32)
1637 		res = hmac_sha256_kdf(prk, hash_len, NULL, info, info_len,
1638 				      z, hash_len);
1639 	else if (hash_len == 48)
1640 		res = hmac_sha384_kdf(prk, hash_len, NULL, info, info_len,
1641 				      z, hash_len);
1642 	else if (hash_len == 64)
1643 		res = hmac_sha512_kdf(prk, hash_len, NULL, info, info_len,
1644 				      z, hash_len);
1645 	else
1646 		res = -1;
1647 	os_free(info);
1648 	os_memset(prk, 0, hash_len);
1649 	if (res < 0)
1650 		return -1;
1651 
1652 	wpa_hexdump_key(MSG_DEBUG, "DPP: z = HKDF-Expand(PRK, info, L)",
1653 			z, hash_len);
1654 	return 0;
1655 }
1656 
1657 
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)1658 int dpp_reconfig_derive_ke_responder(struct dpp_authentication *auth,
1659 				     const u8 *net_access_key,
1660 				     size_t net_access_key_len,
1661 				     struct json_token *peer_net_access_key)
1662 {
1663 	struct crypto_ec_key *own_key = NULL, *peer_key = NULL;
1664 	struct crypto_bignum *sum = NULL;
1665 	const struct crypto_bignum *q, *cR, *pR;
1666 	struct crypto_ec *ec = NULL;
1667 	struct crypto_ec_point *M = NULL;
1668 	const struct crypto_ec_point *CI;
1669 	u8 Mx[DPP_MAX_SHARED_SECRET_LEN];
1670 	u8 prk[DPP_MAX_HASH_LEN];
1671 	const struct dpp_curve_params *curve;
1672 	int res = -1;
1673 	u8 nonces[2 * DPP_MAX_NONCE_LEN];
1674 
1675 	own_key = dpp_set_keypair(&auth->curve, net_access_key,
1676 				  net_access_key_len);
1677 	if (!own_key) {
1678 		dpp_auth_fail(auth, "Failed to parse own netAccessKey");
1679 		goto fail;
1680 	}
1681 
1682 	peer_key = dpp_parse_jwk(peer_net_access_key, &curve);
1683 	if (!peer_key)
1684 		goto fail;
1685 	dpp_debug_print_key("DPP: Received netAccessKey", peer_key);
1686 
1687 	if (auth->curve != curve) {
1688 		wpa_printf(MSG_DEBUG,
1689 			   "DPP: Mismatching netAccessKey curves (own=%s != peer=%s)",
1690 			   auth->curve->name, curve->name);
1691 		goto fail;
1692 	}
1693 
1694 	auth->own_protocol_key = dpp_gen_keypair(curve);
1695 	if (!auth->own_protocol_key)
1696 		goto fail;
1697 
1698 	if (random_get_bytes(auth->e_nonce, auth->curve->nonce_len)) {
1699 		wpa_printf(MSG_ERROR, "DPP: Failed to generate E-nonce");
1700 		goto fail;
1701 	}
1702 	wpa_hexdump_key(MSG_DEBUG, "DPP: E-nonce",
1703 			auth->e_nonce, auth->curve->nonce_len);
1704 
1705 	/* M = { cR + pR } * CI */
1706 	ec = crypto_ec_init(curve->ike_group);
1707 	if (!ec)
1708 		goto fail;
1709 
1710 	sum = crypto_bignum_init();
1711 	q = crypto_ec_get_order(ec);
1712 	M = crypto_ec_point_init(ec);
1713 	cR = crypto_ec_key_get_private_key(own_key);
1714 	pR = crypto_ec_key_get_private_key(auth->own_protocol_key);
1715 	CI = crypto_ec_key_get_public_key(peer_key);
1716 	if (!sum || !q || !M || !cR || !pR || !CI ||
1717 	    crypto_bignum_addmod(cR, pR, q, sum) ||
1718 	    crypto_ec_point_mul(ec, CI, sum, M) ||
1719 	    crypto_ec_point_to_bin(ec, M, Mx, NULL)) {
1720 		wpa_printf(MSG_ERROR, "DPP: Error during M computation");
1721 		goto fail;
1722 	}
1723 	wpa_hexdump_key(MSG_DEBUG, "DPP: M.x", Mx, curve->prime_len);
1724 
1725 	/* ke = HKDF(C-nonce | E-nonce, "dpp reconfig key", M.x) */
1726 
1727 	/* HKDF-Extract(C-nonce | E-nonce, M.x) */
1728 	os_memcpy(nonces, auth->c_nonce, curve->nonce_len);
1729 	os_memcpy(&nonces[curve->nonce_len], auth->e_nonce, curve->nonce_len);
1730 	if (dpp_hmac(curve->hash_len, nonces, 2 * curve->nonce_len,
1731 		     Mx, curve->prime_len, prk) < 0)
1732 		goto fail;
1733 	wpa_hexdump_key(MSG_DEBUG, "DPP: PRK", prk, curve->hash_len);
1734 
1735 	/* HKDF-Expand(PRK, "dpp reconfig key", L) */
1736 	if (dpp_hkdf_expand(curve->hash_len, prk, curve->hash_len,
1737 			    "dpp reconfig key", auth->ke, curve->hash_len) < 0)
1738 		goto fail;
1739 	wpa_hexdump_key(MSG_DEBUG,
1740 			"DPP: ke = HKDF(C-nonce | E-nonce, \"dpp reconfig key\", M.x)",
1741 			auth->ke, curve->hash_len);
1742 
1743 	res = 0;
1744 	crypto_ec_key_deinit(auth->reconfig_old_protocol_key);
1745 	auth->reconfig_old_protocol_key = own_key;
1746 	own_key = NULL;
1747 fail:
1748 	forced_memzero(prk, sizeof(prk));
1749 	forced_memzero(Mx, sizeof(Mx));
1750 	crypto_ec_point_deinit(M, 1);
1751 	crypto_bignum_deinit(sum, 1);
1752 	crypto_ec_key_deinit(own_key);
1753 	crypto_ec_key_deinit(peer_key);
1754 	crypto_ec_deinit(ec);
1755 	return res;
1756 }
1757 
1758 
dpp_reconfig_derive_ke_initiator(struct dpp_authentication * auth,const u8 * r_proto,u16 r_proto_len,struct json_token * net_access_key)1759 int dpp_reconfig_derive_ke_initiator(struct dpp_authentication *auth,
1760 				     const u8 *r_proto, u16 r_proto_len,
1761 				     struct json_token *net_access_key)
1762 {
1763 	struct crypto_ec_key *pr = NULL, *peer_key = NULL;
1764 	const struct crypto_ec_point *CR, *PR;
1765 	const struct crypto_bignum *cI;
1766 	struct crypto_ec *ec = NULL;
1767 	struct crypto_ec_point *sum = NULL, *M = NULL;
1768 	u8 Mx[DPP_MAX_SHARED_SECRET_LEN];
1769 	u8 prk[DPP_MAX_HASH_LEN];
1770 	int res = -1;
1771 	const struct dpp_curve_params *curve;
1772 	u8 nonces[2 * DPP_MAX_NONCE_LEN];
1773 
1774 	pr = dpp_set_pubkey_point(auth->conf->connector_key,
1775 				  r_proto, r_proto_len);
1776 	if (!pr) {
1777 		dpp_auth_fail(auth, "Invalid Responder Protocol Key");
1778 		goto fail;
1779 	}
1780 	dpp_debug_print_key("Peer (Responder) Protocol Key", pr);
1781 	crypto_ec_key_deinit(auth->peer_protocol_key);
1782 	auth->peer_protocol_key = pr;
1783 	pr = NULL;
1784 
1785 	peer_key = dpp_parse_jwk(net_access_key, &curve);
1786 	if (!peer_key)
1787 		goto fail;
1788 	dpp_debug_print_key("DPP: Received netAccessKey", peer_key);
1789 	if (auth->curve != curve) {
1790 		wpa_printf(MSG_DEBUG,
1791 			   "DPP: Mismatching netAccessKey curves (own=%s != peer=%s)",
1792 			   auth->curve->name, curve->name);
1793 		goto fail;
1794 	}
1795 
1796 	/* M = cI * { CR + PR } */
1797 	ec = crypto_ec_init(curve->ike_group);
1798 	if (!ec)
1799 		goto fail;
1800 
1801 	cI = crypto_ec_key_get_private_key(auth->conf->connector_key);
1802 	sum = crypto_ec_point_init(ec);
1803 	M = crypto_ec_point_init(ec);
1804 	CR = crypto_ec_key_get_public_key(peer_key);
1805 	PR = crypto_ec_key_get_public_key(auth->peer_protocol_key);
1806 	if (!cI || !sum || !M || !CR || !PR ||
1807 	    crypto_ec_point_add(ec, CR, PR, sum) ||
1808 	    crypto_ec_point_mul(ec, sum, cI, M) ||
1809 	    crypto_ec_point_to_bin(ec, M, Mx, NULL)) {
1810 		wpa_printf(MSG_ERROR, "DPP: Error during M computation");
1811 		goto fail;
1812 	}
1813 
1814 	wpa_hexdump_key(MSG_DEBUG, "DPP: M.x", Mx, curve->prime_len);
1815 
1816 	/* ke = HKDF(C-nonce | E-nonce, "dpp reconfig key", M.x) */
1817 
1818 	/* HKDF-Extract(C-nonce | E-nonce, M.x) */
1819 	os_memcpy(nonces, auth->c_nonce, curve->nonce_len);
1820 	os_memcpy(&nonces[curve->nonce_len], auth->e_nonce, curve->nonce_len);
1821 	if (dpp_hmac(curve->hash_len, nonces, 2 * curve->nonce_len,
1822 		     Mx, curve->prime_len, prk) < 0)
1823 		goto fail;
1824 	wpa_hexdump_key(MSG_DEBUG, "DPP: PRK", prk, curve->hash_len);
1825 
1826 	/* HKDF-Expand(PRK, "dpp reconfig key", L) */
1827 	if (dpp_hkdf_expand(curve->hash_len, prk, curve->hash_len,
1828 			    "dpp reconfig key", auth->ke, curve->hash_len) < 0)
1829 		goto fail;
1830 	wpa_hexdump_key(MSG_DEBUG,
1831 			"DPP: ke = HKDF(C-nonce | E-nonce, \"dpp reconfig key\", M.x)",
1832 			auth->ke, curve->hash_len);
1833 
1834 	res = 0;
1835 fail:
1836 	forced_memzero(prk, sizeof(prk));
1837 	forced_memzero(Mx, sizeof(Mx));
1838 	crypto_ec_key_deinit(pr);
1839 	crypto_ec_key_deinit(peer_key);
1840 	crypto_ec_point_deinit(sum, 1);
1841 	crypto_ec_point_deinit(M, 1);
1842 	crypto_ec_deinit(ec);
1843 	return res;
1844 }
1845 
1846 
1847 static char *
dpp_build_jws_prot_hdr(struct dpp_configurator * conf,size_t * signed1_len)1848 dpp_build_jws_prot_hdr(struct dpp_configurator *conf, size_t *signed1_len)
1849 {
1850 	struct wpabuf *jws_prot_hdr;
1851 	char *signed1;
1852 
1853 	jws_prot_hdr = wpabuf_alloc(100);
1854 	if (!jws_prot_hdr)
1855 		return NULL;
1856 	json_start_object(jws_prot_hdr, NULL);
1857 	json_add_string(jws_prot_hdr, "typ", "dppCon");
1858 	json_value_sep(jws_prot_hdr);
1859 	json_add_string(jws_prot_hdr, "kid", conf->kid);
1860 	json_value_sep(jws_prot_hdr);
1861 	json_add_string(jws_prot_hdr, "alg", conf->curve->jws_alg);
1862 	json_end_object(jws_prot_hdr);
1863 	signed1 = base64_url_encode(wpabuf_head(jws_prot_hdr),
1864 				    wpabuf_len(jws_prot_hdr),
1865 				    signed1_len);
1866 	wpabuf_free(jws_prot_hdr);
1867 	return signed1;
1868 }
1869 
1870 
1871 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)1872 dpp_build_conn_signature(struct dpp_configurator *conf,
1873 			 const char *signed1, size_t signed1_len,
1874 			 const char *signed2, size_t signed2_len,
1875 			 size_t *signed3_len)
1876 {
1877 	const struct dpp_curve_params *curve;
1878 	struct wpabuf *sig = NULL;
1879 	char *signed3 = NULL;
1880 	char *dot = ".";
1881 	const u8 *vector[3];
1882 	size_t vector_len[3];
1883 	u8 *hash;
1884 	int ret;
1885 
1886 	vector[0] = (const u8 *) signed1;
1887 	vector[1] = (const u8 *) dot;
1888 	vector[2] = (const u8 *) signed2;
1889 	vector_len[0] = signed1_len;
1890 	vector_len[1] = 1;
1891 	vector_len[2] = signed2_len;
1892 
1893 	curve = conf->curve;
1894 	hash = os_malloc(curve->hash_len);
1895 	if (!hash)
1896 		goto fail;
1897 	if (curve->hash_len == SHA256_MAC_LEN) {
1898 		ret = sha256_vector(3, vector, vector_len, hash);
1899 	} else if (curve->hash_len == SHA384_MAC_LEN) {
1900 		ret = sha384_vector(3, vector, vector_len, hash);
1901 	} else if (curve->hash_len == SHA512_MAC_LEN) {
1902 		ret = sha512_vector(3, vector, vector_len, hash);
1903 	} else {
1904 		wpa_printf(MSG_DEBUG, "DPP: Unknown signature algorithm");
1905 		goto fail;
1906 	}
1907 	if (ret) {
1908 		wpa_printf(MSG_DEBUG, "DPP: Hash computation failed");
1909 		goto fail;
1910 	}
1911 	wpa_hexdump(MSG_DEBUG, "DPP: Hash value for Connector signature",
1912 		    hash, curve->hash_len);
1913 
1914 	sig = crypto_ec_key_sign_r_s(conf->csign, hash, curve->hash_len);
1915 	if (!sig) {
1916 		wpa_printf(MSG_ERROR, "DPP: Signature computation failed");
1917 		goto fail;
1918 	}
1919 
1920 	wpa_hexdump(MSG_DEBUG, "DPP: signedConnector ECDSA signature (raw r,s)",
1921 		    wpabuf_head(sig), wpabuf_len(sig));
1922 	signed3 = base64_url_encode(wpabuf_head(sig), wpabuf_len(sig),
1923 				    signed3_len);
1924 
1925 fail:
1926 	os_free(hash);
1927 	wpabuf_free(sig);
1928 	return signed3;
1929 }
1930 
dpp_sign_connector(struct dpp_configurator * conf,const struct wpabuf * dppcon)1931 char * dpp_sign_connector(struct dpp_configurator *conf,
1932 			  const struct wpabuf *dppcon)
1933 {
1934 	char *signed1 = NULL, *signed2 = NULL, *signed3 = NULL;
1935 	char *signed_conn = NULL, *pos;
1936 	size_t signed1_len, signed2_len, signed3_len;
1937 
1938 	signed1 = dpp_build_jws_prot_hdr(conf, &signed1_len);
1939 	signed2 = base64_url_encode(wpabuf_head(dppcon), wpabuf_len(dppcon),
1940 				    &signed2_len);
1941 	if (!signed1 || !signed2)
1942 		goto fail;
1943 
1944 	signed3 = dpp_build_conn_signature(conf, signed1, signed1_len,
1945 					   signed2, signed2_len, &signed3_len);
1946 	if (!signed3)
1947 		goto fail;
1948 
1949 	signed_conn = os_malloc(signed1_len + signed2_len + signed3_len + 3);
1950 	if (!signed_conn)
1951 		goto fail;
1952 	pos = signed_conn;
1953 	os_memcpy(pos, signed1, signed1_len);
1954 	pos += signed1_len;
1955 	*pos++ = '.';
1956 	os_memcpy(pos, signed2, signed2_len);
1957 	pos += signed2_len;
1958 	*pos++ = '.';
1959 	os_memcpy(pos, signed3, signed3_len);
1960 	pos += signed3_len;
1961 	*pos = '\0';
1962 
1963 fail:
1964 	os_free(signed1);
1965 	os_free(signed2);
1966 	os_free(signed3);
1967 	return signed_conn;
1968 }
1969 
1970 
1971 #ifdef CONFIG_DPP2
1972 
dpp_pfs_init(const u8 * net_access_key,size_t net_access_key_len)1973 struct dpp_pfs * dpp_pfs_init(const u8 *net_access_key,
1974 			      size_t net_access_key_len)
1975 {
1976 	struct wpabuf *pub = NULL;
1977 	struct crypto_ec_key *own_key;
1978 	struct dpp_pfs *pfs;
1979 
1980 	pfs = os_zalloc(sizeof(*pfs));
1981 	if (!pfs)
1982 		return NULL;
1983 
1984 	own_key = dpp_set_keypair(&pfs->curve, net_access_key,
1985 				  net_access_key_len);
1986 	if (!own_key) {
1987 		wpa_printf(MSG_ERROR, "DPP: Failed to parse own netAccessKey");
1988 		goto fail;
1989 	}
1990 	crypto_ec_key_deinit(own_key);
1991 
1992 	pfs->ecdh = crypto_ecdh_init(pfs->curve->ike_group);
1993 	if (!pfs->ecdh)
1994 		goto fail;
1995 
1996 	pub = crypto_ecdh_get_pubkey(pfs->ecdh, 0);
1997 	pub = wpabuf_zeropad(pub, pfs->curve->prime_len);
1998 	if (!pub)
1999 		goto fail;
2000 
2001 	pfs->ie = wpabuf_alloc(5 + wpabuf_len(pub));
2002 	if (!pfs->ie)
2003 		goto fail;
2004 	wpabuf_put_u8(pfs->ie, WLAN_EID_EXTENSION);
2005 	wpabuf_put_u8(pfs->ie, 1 + 2 + wpabuf_len(pub));
2006 	wpabuf_put_u8(pfs->ie, WLAN_EID_EXT_OWE_DH_PARAM);
2007 	wpabuf_put_le16(pfs->ie, pfs->curve->ike_group);
2008 	wpabuf_put_buf(pfs->ie, pub);
2009 	wpabuf_free(pub);
2010 	wpa_hexdump_buf(MSG_DEBUG, "DPP: Diffie-Hellman Parameter element",
2011 			pfs->ie);
2012 
2013 	return pfs;
2014 fail:
2015 	wpabuf_free(pub);
2016 	dpp_pfs_free(pfs);
2017 	return NULL;
2018 }
2019 
2020 
dpp_pfs_process(struct dpp_pfs * pfs,const u8 * peer_ie,size_t peer_ie_len)2021 int dpp_pfs_process(struct dpp_pfs *pfs, const u8 *peer_ie, size_t peer_ie_len)
2022 {
2023 	if (peer_ie_len < 2)
2024 		return -1;
2025 	if (WPA_GET_LE16(peer_ie) != pfs->curve->ike_group) {
2026 		wpa_printf(MSG_DEBUG, "DPP: Peer used different group for PFS");
2027 		return -1;
2028 	}
2029 
2030 	pfs->secret = crypto_ecdh_set_peerkey(pfs->ecdh, 0, peer_ie + 2,
2031 					      peer_ie_len - 2);
2032 	pfs->secret = wpabuf_zeropad(pfs->secret, pfs->curve->prime_len);
2033 	if (!pfs->secret) {
2034 		wpa_printf(MSG_DEBUG, "DPP: Invalid peer DH public key");
2035 		return -1;
2036 	}
2037 	wpa_hexdump_buf_key(MSG_DEBUG, "DPP: DH shared secret", pfs->secret);
2038 	return 0;
2039 }
2040 
2041 
dpp_pfs_free(struct dpp_pfs * pfs)2042 void dpp_pfs_free(struct dpp_pfs *pfs)
2043 {
2044 	if (!pfs)
2045 		return;
2046 	crypto_ecdh_deinit(pfs->ecdh);
2047 	wpabuf_free(pfs->ie);
2048 	wpabuf_clear_free(pfs->secret);
2049 	os_free(pfs);
2050 }
2051 
2052 
dpp_build_csr(struct dpp_authentication * auth,const char * name)2053 struct wpabuf * dpp_build_csr(struct dpp_authentication *auth, const char *name)
2054 {
2055 	struct crypto_csr *csr = NULL;
2056 	struct wpabuf *buf = NULL;
2057 	struct crypto_ec_key *key;
2058 	unsigned int hash_len = auth->curve->hash_len;
2059 	struct wpabuf *priv_key;
2060 	u8 cp[DPP_CP_LEN];
2061 	char *password = NULL;
2062 	size_t password_len;
2063 	int hash_sign_algo;
2064 
2065 	/* TODO: use auth->csrattrs */
2066 
2067 	/* TODO: support generation of a new private key if csrAttrs requests
2068 	 * a specific group to be used */
2069 	key = auth->own_protocol_key;
2070 
2071 	priv_key = crypto_ec_key_get_ecprivate_key(key, true);
2072 	if (!priv_key)
2073 		goto fail;
2074 	wpabuf_free(auth->priv_key);
2075 	auth->priv_key = priv_key;
2076 
2077 	csr = crypto_csr_init();
2078 	if (!csr || crypto_csr_set_ec_public_key(csr, key))
2079 		goto fail;
2080 
2081 	if (name && crypto_csr_set_name(csr, CSR_NAME_CN, name))
2082 		goto fail;
2083 
2084 	/* cp = HKDF-Expand(bk, "CSR challengePassword", 64) */
2085 	if (dpp_hkdf_expand(hash_len, auth->bk, hash_len,
2086 			    "CSR challengePassword", cp, DPP_CP_LEN) < 0)
2087 		goto fail;
2088 	wpa_hexdump_key(MSG_DEBUG,
2089 			"DPP: cp = HKDF-Expand(bk, \"CSR challengePassword\", 64)",
2090 			cp, DPP_CP_LEN);
2091 	password = base64_encode_no_lf(cp, DPP_CP_LEN, &password_len);
2092 	forced_memzero(cp, DPP_CP_LEN);
2093 	if (!password ||
2094 	    crypto_csr_set_attribute(csr, CSR_ATTR_CHALLENGE_PASSWORD,
2095 				     ASN1_TAG_UTF8STRING, (const u8 *) password,
2096 				     password_len))
2097 		goto fail;
2098 
2099 	/* TODO: hash func selection based on csrAttrs */
2100 	if (hash_len == SHA256_MAC_LEN) {
2101 		hash_sign_algo = CRYPTO_HASH_ALG_SHA256;
2102 	} else if (hash_len == SHA384_MAC_LEN) {
2103 		hash_sign_algo = CRYPTO_HASH_ALG_SHA384;
2104 	} else if (hash_len == SHA512_MAC_LEN) {
2105 		hash_sign_algo = CRYPTO_HASH_ALG_SHA512;
2106 	} else {
2107 		wpa_printf(MSG_DEBUG, "DPP: Unknown signature algorithm");
2108 		goto fail;
2109 	}
2110 
2111 	buf = crypto_csr_sign(csr, key, hash_sign_algo);
2112 	if (!buf)
2113 		goto fail;
2114 	wpa_hexdump_buf(MSG_DEBUG, "DPP: CSR", buf);
2115 
2116 fail:
2117 	bin_clear_free(password, password_len);
2118 	crypto_csr_deinit(csr);
2119 	return buf;
2120 }
2121 
2122 
dpp_validate_csr(struct dpp_authentication * auth,const struct wpabuf * csrbuf)2123 int dpp_validate_csr(struct dpp_authentication *auth,
2124 		     const struct wpabuf *csrbuf)
2125 {
2126 	struct crypto_csr *csr;
2127 	const u8 *attr;
2128 	size_t attr_len;
2129 	int attr_type;
2130 	unsigned char *cp = NULL;
2131 	size_t cp_len;
2132 	u8 exp_cp[DPP_CP_LEN];
2133 	unsigned int hash_len = auth->curve->hash_len;
2134 	int ret = -1;
2135 
2136 	csr = crypto_csr_verify(csrbuf);
2137 	if (!csr) {
2138 		wpa_printf(MSG_DEBUG,
2139 			   "DPP: CSR invalid or invalid signature");
2140 		goto fail;
2141 	}
2142 
2143 	attr = crypto_csr_get_attribute(csr, CSR_ATTR_CHALLENGE_PASSWORD,
2144 					&attr_len, &attr_type);
2145 	if (!attr) {
2146 		wpa_printf(MSG_DEBUG,
2147 			   "DPP: CSR does not include challengePassword");
2148 		goto fail;
2149 	}
2150 	/* This is supposed to be UTF8String, but allow other strings as well
2151 	 * since challengePassword is using ASCII (base64 encoded). */
2152 	if (attr_type != ASN1_TAG_UTF8STRING &&
2153 	    attr_type != ASN1_TAG_PRINTABLESTRING &&
2154 	    attr_type != ASN1_TAG_IA5STRING) {
2155 		wpa_printf(MSG_DEBUG,
2156 			   "DPP: Unexpected challengePassword attribute type %d",
2157 			   attr_type);
2158 		goto fail;
2159 	}
2160 
2161 	cp = base64_decode((const char *) attr, attr_len, &cp_len);
2162 	if (!cp) {
2163 		wpa_printf(MSG_DEBUG,
2164 			   "DPP: Could not base64 decode challengePassword");
2165 		goto fail;
2166 	}
2167 	if (cp_len != DPP_CP_LEN) {
2168 		wpa_printf(MSG_DEBUG,
2169 			   "DPP: Unexpected cp length (%zu) in CSR challengePassword",
2170 			   cp_len);
2171 		goto fail;
2172 	}
2173 	wpa_hexdump_key(MSG_DEBUG, "DPP: cp from CSR challengePassword",
2174 			cp, cp_len);
2175 
2176 	/* cp = HKDF-Expand(bk, "CSR challengePassword", 64) */
2177 	if (dpp_hkdf_expand(hash_len, auth->bk, hash_len,
2178 			    "CSR challengePassword", exp_cp, DPP_CP_LEN) < 0)
2179 		goto fail;
2180 	wpa_hexdump_key(MSG_DEBUG,
2181 			"DPP: cp = HKDF-Expand(bk, \"CSR challengePassword\", 64)",
2182 			exp_cp, DPP_CP_LEN);
2183 	if (os_memcmp_const(cp, exp_cp, DPP_CP_LEN) != 0) {
2184 		wpa_printf(MSG_DEBUG,
2185 			   "DPP: CSR challengePassword does not match calculated cp");
2186 		goto fail;
2187 	}
2188 
2189 	ret = 0;
2190 fail:
2191 	os_free(cp);
2192 	crypto_csr_deinit(csr);
2193 	return ret;
2194 }
2195 
2196 
dpp_gen_reconfig_id(const u8 * csign_key,size_t csign_key_len,const u8 * pp_key,size_t pp_key_len)2197 struct dpp_reconfig_id * dpp_gen_reconfig_id(const u8 *csign_key,
2198 					     size_t csign_key_len,
2199 					     const u8 *pp_key,
2200 					     size_t pp_key_len)
2201 {
2202 	struct crypto_ec_key *csign = NULL, *ppkey = NULL;
2203 	struct dpp_reconfig_id *id = NULL;
2204 	struct crypto_ec *ec = NULL;
2205 	const struct crypto_bignum *q;
2206 	struct crypto_bignum *bn = NULL;
2207 	struct crypto_ec_point *e_id = NULL;
2208 	const struct crypto_ec_point *generator;
2209 
2210 	csign = crypto_ec_key_parse_pub(csign_key, csign_key_len);
2211 	if (!csign)
2212 		goto fail;
2213 
2214 	if (!pp_key)
2215 		goto fail;
2216 	ppkey = crypto_ec_key_parse_pub(pp_key, pp_key_len);
2217 	if (!ppkey)
2218 		goto fail;
2219 
2220 	ec = crypto_ec_init(crypto_ec_key_group(csign));
2221 	if (!ec)
2222 		goto fail;
2223 
2224 	e_id = crypto_ec_point_init(ec);
2225 	bn = crypto_bignum_init();
2226 	q = crypto_ec_get_order(ec);
2227 	generator = crypto_ec_get_generator(ec);
2228 	if (!e_id || !bn || !q || !generator ||
2229 	    crypto_bignum_rand(bn, q) ||
2230 	    crypto_ec_point_mul(ec, generator, bn, e_id))
2231 		goto fail;
2232 
2233 	crypto_ec_point_debug_print(ec, e_id,
2234 				    "DPP: Generated random point E-id");
2235 
2236 	id = os_zalloc(sizeof(*id));
2237 	if (!id)
2238 		goto fail;
2239 
2240 	id->ec = ec;
2241 	ec = NULL;
2242 	id->e_id = e_id;
2243 	e_id = NULL;
2244 	id->csign = csign;
2245 	csign = NULL;
2246 	id->pp_key = ppkey;
2247 	ppkey = NULL;
2248 fail:
2249 	crypto_ec_point_deinit(e_id, 1);
2250 	crypto_ec_key_deinit(csign);
2251 	crypto_ec_key_deinit(ppkey);
2252 	crypto_bignum_deinit(bn, 1);
2253 	crypto_ec_deinit(ec);
2254 	return id;
2255 }
2256 
2257 
dpp_update_reconfig_id(struct dpp_reconfig_id * id)2258 int dpp_update_reconfig_id(struct dpp_reconfig_id *id)
2259 {
2260 	const struct crypto_bignum *q;
2261 	struct crypto_bignum *bn;
2262 	const struct crypto_ec_point *pp, *generator;
2263 	struct crypto_ec_point *e_prime_id, *a_nonce;
2264 	int ret = -1;
2265 
2266 	pp = crypto_ec_key_get_public_key(id->pp_key);
2267 	e_prime_id = crypto_ec_point_init(id->ec);
2268 	a_nonce = crypto_ec_point_init(id->ec);
2269 	bn = crypto_bignum_init();
2270 	q = crypto_ec_get_order(id->ec);
2271 	generator = crypto_ec_get_generator(id->ec);
2272 
2273 	/* Generate random 0 <= a-nonce < q
2274 	 * A-NONCE = a-nonce * G
2275 	 * E'-id = E-id + a-nonce * P_pk */
2276 	if (!pp || !e_prime_id || !a_nonce || !bn || !q || !generator ||
2277 	    crypto_bignum_rand(bn, q) || /* bn = a-nonce */
2278 	    crypto_ec_point_mul(id->ec, generator, bn, a_nonce) ||
2279 	    crypto_ec_point_mul(id->ec, pp, bn, e_prime_id) ||
2280 	    crypto_ec_point_add(id->ec, id->e_id, e_prime_id, e_prime_id))
2281 		goto fail;
2282 
2283 	crypto_ec_point_debug_print(id->ec, a_nonce,
2284 				    "DPP: Generated A-NONCE");
2285 	crypto_ec_point_debug_print(id->ec, e_prime_id,
2286 				    "DPP: Encrypted E-id to E'-id");
2287 
2288 	crypto_ec_key_deinit(id->a_nonce);
2289 	crypto_ec_key_deinit(id->e_prime_id);
2290 	id->a_nonce = crypto_ec_key_set_pub_point(id->ec, a_nonce);
2291 	id->e_prime_id = crypto_ec_key_set_pub_point(id->ec, e_prime_id);
2292 	if (!id->a_nonce || !id->e_prime_id)
2293 		goto fail;
2294 
2295 	ret = 0;
2296 
2297 fail:
2298 	crypto_ec_point_deinit(e_prime_id, 1);
2299 	crypto_ec_point_deinit(a_nonce, 1);
2300 	crypto_bignum_deinit(bn, 1);
2301 	return ret;
2302 }
2303 
2304 
dpp_free_reconfig_id(struct dpp_reconfig_id * id)2305 void dpp_free_reconfig_id(struct dpp_reconfig_id *id)
2306 {
2307 	if (id) {
2308 		crypto_ec_point_deinit(id->e_id, 1);
2309 		crypto_ec_key_deinit(id->csign);
2310 		crypto_ec_key_deinit(id->a_nonce);
2311 		crypto_ec_key_deinit(id->e_prime_id);
2312 		crypto_ec_key_deinit(id->pp_key);
2313 		crypto_ec_deinit(id->ec);
2314 		os_free(id);
2315 	}
2316 }
2317 
2318 
dpp_decrypt_e_id(struct crypto_ec_key * ppkey,struct crypto_ec_key * a_nonce,struct crypto_ec_key * e_prime_id)2319 struct crypto_ec_point * dpp_decrypt_e_id(struct crypto_ec_key *ppkey,
2320 					  struct crypto_ec_key *a_nonce,
2321 					  struct crypto_ec_key *e_prime_id)
2322 {
2323 	struct crypto_ec *ec;
2324 	const struct crypto_bignum *pp;
2325 	struct crypto_ec_point *e_id = NULL;
2326 	const struct crypto_ec_point *a_nonce_point, *e_prime_id_point;
2327 
2328 	if (!ppkey)
2329 		return NULL;
2330 
2331 	/* E-id = E'-id - s_C * A-NONCE */
2332 	ec = crypto_ec_init(crypto_ec_key_group(ppkey));
2333 	if (!ec)
2334 		return NULL;
2335 
2336 	pp = crypto_ec_key_get_private_key(ppkey);
2337 	a_nonce_point = crypto_ec_key_get_public_key(a_nonce);
2338 	e_prime_id_point = crypto_ec_key_get_public_key(e_prime_id);
2339 	e_id = crypto_ec_point_init(ec);
2340 	if (!pp || !a_nonce_point || !e_prime_id_point || !e_id ||
2341 	    crypto_ec_point_mul(ec, a_nonce_point, pp, e_id) ||
2342 	    crypto_ec_point_invert(ec, e_id) ||
2343 	    crypto_ec_point_add(ec, e_id, e_prime_id_point, e_id)) {
2344 		crypto_ec_point_deinit(e_id, 1);
2345 		goto fail;
2346 	}
2347 
2348 	crypto_ec_point_debug_print(ec, e_id, "DPP: Decrypted E-id");
2349 
2350 fail:
2351 	crypto_ec_deinit(ec);
2352 	return e_id;
2353 }
2354 
2355 #endif /* CONFIG_DPP2 */
2356 
2357 
2358 #ifdef CONFIG_TESTING_OPTIONS
2359 
dpp_test_gen_invalid_key(struct wpabuf * msg,const struct dpp_curve_params * curve)2360 int dpp_test_gen_invalid_key(struct wpabuf *msg,
2361 			     const struct dpp_curve_params *curve)
2362 {
2363 	struct crypto_ec *ec;
2364 	struct crypto_ec_key *key = NULL;
2365 	const struct crypto_ec_point *pub_key;
2366 	struct crypto_ec_point *p = NULL;
2367 	u8 *x, *y;
2368 	int ret = -1;
2369 
2370 	ec = crypto_ec_init(curve->ike_group);
2371 	x = wpabuf_put(msg, curve->prime_len);
2372 	y = wpabuf_put(msg, curve->prime_len);
2373 	if (!ec)
2374 		goto fail;
2375 
2376 retry:
2377 	/* Generate valid key pair */
2378 	key = crypto_ec_key_gen(curve->ike_group);
2379 	if (!key)
2380 		goto fail;
2381 
2382 	/* Retrieve public key coordinates */
2383 	pub_key = crypto_ec_key_get_public_key(key);
2384 	if (!pub_key)
2385 		goto fail;
2386 
2387 	crypto_ec_point_to_bin(ec, pub_key, x, y);
2388 
2389 	/* And corrupt them */
2390 	y[curve->prime_len - 1] ^= 0x01;
2391 	p = crypto_ec_point_from_bin(ec, x);
2392 	if (p && crypto_ec_point_is_on_curve(ec, p)) {
2393 		crypto_ec_point_deinit(p, 0);
2394 		p = NULL;
2395 		goto retry;
2396 	}
2397 
2398 	ret = 0;
2399 fail:
2400 	crypto_ec_point_deinit(p, 0);
2401 	crypto_ec_key_deinit(key);
2402 	crypto_ec_deinit(ec);
2403 	return ret;
2404 }
2405 
2406 
dpp_corrupt_connector_signature(const char * connector)2407 char * dpp_corrupt_connector_signature(const char *connector)
2408 {
2409 	char *tmp, *pos, *signed3 = NULL;
2410 	unsigned char *signature = NULL;
2411 	size_t signature_len = 0, signed3_len;
2412 
2413 	tmp = os_zalloc(os_strlen(connector) + 5);
2414 	if (!tmp)
2415 		goto fail;
2416 	os_memcpy(tmp, connector, os_strlen(connector));
2417 
2418 	pos = os_strchr(tmp, '.');
2419 	if (!pos)
2420 		goto fail;
2421 
2422 	pos = os_strchr(pos + 1, '.');
2423 	if (!pos)
2424 		goto fail;
2425 	pos++;
2426 
2427 	wpa_printf(MSG_DEBUG, "DPP: Original base64url encoded signature: %s",
2428 		   pos);
2429 	signature = base64_url_decode(pos, os_strlen(pos), &signature_len);
2430 	if (!signature || signature_len == 0)
2431 		goto fail;
2432 	wpa_hexdump(MSG_DEBUG, "DPP: Original Connector signature",
2433 		    signature, signature_len);
2434 	signature[signature_len - 1] ^= 0x01;
2435 	wpa_hexdump(MSG_DEBUG, "DPP: Corrupted Connector signature",
2436 		    signature, signature_len);
2437 	signed3 = base64_url_encode(signature, signature_len, &signed3_len);
2438 	if (!signed3)
2439 		goto fail;
2440 	os_memcpy(pos, signed3, signed3_len);
2441 	pos[signed3_len] = '\0';
2442 	wpa_printf(MSG_DEBUG, "DPP: Corrupted base64url encoded signature: %s",
2443 		   pos);
2444 
2445 out:
2446 	os_free(signature);
2447 	os_free(signed3);
2448 	return tmp;
2449 fail:
2450 	os_free(tmp);
2451 	tmp = NULL;
2452 	goto out;
2453 }
2454 
2455 #endif /* CONFIG_TESTING_OPTIONS */
2456