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