Home | History | Annotate | Line # | Download | only in common
      1 /*
      2  * DPP crypto functionality
      3  * Copyright (c) 2017, Qualcomm Atheros, Inc.
      4  * Copyright (c) 2018-2020, The Linux Foundation
      5  *
      6  * This software may be distributed under the terms of the BSD license.
      7  * See README for more details.
      8  */
      9 
     10 #include "utils/includes.h"
     11 
     12 #include "utils/common.h"
     13 #include "utils/base64.h"
     14 #include "utils/json.h"
     15 #include "common/ieee802_11_defs.h"
     16 #include "crypto/crypto.h"
     17 #include "crypto/random.h"
     18 #include "crypto/sha384.h"
     19 #include "crypto/sha512.h"
     20 #include "tls/asn1.h"
     21 #include "dpp.h"
     22 #include "dpp_i.h"
     23 
     24 
     25 static const struct dpp_curve_params dpp_curves[] = {
     26 	/* The mandatory to support and the default NIST P-256 curve needs to
     27 	 * be the first entry on this list. */
     28 	{ "prime256v1", 32, 32, 16, 32, "P-256", 19, "ES256" },
     29 	{ "secp384r1", 48, 48, 24, 48, "P-384", 20, "ES384" },
     30 	{ "secp521r1", 64, 64, 32, 66, "P-521", 21, "ES512" },
     31 	{ "brainpoolP256r1", 32, 32, 16, 32, "BP-256", 28, "BS256" },
     32 	{ "brainpoolP384r1", 48, 48, 24, 48, "BP-384", 29, "BS384" },
     33 	{ "brainpoolP512r1", 64, 64, 32, 64, "BP-512", 30, "BS512" },
     34 	{ NULL, 0, 0, 0, 0, NULL, 0, NULL }
     35 };
     36 
     37 
     38 const struct dpp_curve_params * dpp_get_curve_name(const char *name)
     39 {
     40 	int i;
     41 
     42 	if (!name)
     43 		return &dpp_curves[0];
     44 
     45 	for (i = 0; dpp_curves[i].name; i++) {
     46 		if (os_strcmp(name, dpp_curves[i].name) == 0 ||
     47 		    (dpp_curves[i].jwk_crv &&
     48 		     os_strcmp(name, dpp_curves[i].jwk_crv) == 0))
     49 			return &dpp_curves[i];
     50 	}
     51 	return NULL;
     52 }
     53 
     54 
     55 const struct dpp_curve_params * dpp_get_curve_jwk_crv(const char *name)
     56 {
     57 	int i;
     58 
     59 	for (i = 0; dpp_curves[i].name; i++) {
     60 		if (dpp_curves[i].jwk_crv &&
     61 		    os_strcmp(name, dpp_curves[i].jwk_crv) == 0)
     62 			return &dpp_curves[i];
     63 	}
     64 	return NULL;
     65 }
     66 
     67 
     68 const struct dpp_curve_params * dpp_get_curve_ike_group(u16 group)
     69 {
     70 	int i;
     71 
     72 	for (i = 0; dpp_curves[i].name; i++) {
     73 		if (dpp_curves[i].ike_group == group)
     74 			return &dpp_curves[i];
     75 	}
     76 	return NULL;
     77 }
     78 
     79 
     80 void dpp_debug_print_key(const char *title, struct crypto_ec_key *key)
     81 {
     82 	struct wpabuf *der = NULL;
     83 
     84 	crypto_ec_key_debug_print(key, title);
     85 
     86 	der = crypto_ec_key_get_ecprivate_key(key, true);
     87 	if (der) {
     88 		wpa_hexdump_buf_key(MSG_DEBUG, "DPP: ECPrivateKey", der);
     89 	} else {
     90 		der = crypto_ec_key_get_subject_public_key(key);
     91 		if (der)
     92 			wpa_hexdump_buf_key(MSG_DEBUG, "DPP: EC_PUBKEY", der);
     93 	}
     94 
     95 	wpabuf_clear_free(der);
     96 }
     97 
     98 
     99 static int dpp_hash_vector(const struct dpp_curve_params *curve,
    100 			   size_t num_elem, const u8 *addr[], const size_t *len,
    101 			   u8 *mac)
    102 {
    103 	if (curve->hash_len == 32)
    104 		return sha256_vector(num_elem, addr, len, mac);
    105 	if (curve->hash_len == 48)
    106 		return sha384_vector(num_elem, addr, len, mac);
    107 	if (curve->hash_len == 64)
    108 		return sha512_vector(num_elem, addr, len, mac);
    109 	return -1;
    110 }
    111 
    112 
    113 int dpp_hkdf_expand(size_t hash_len, const u8 *secret, size_t secret_len,
    114 		    const char *label, u8 *out, size_t outlen)
    115 {
    116 	if (hash_len == 32)
    117 		return hmac_sha256_kdf(secret, secret_len, NULL,
    118 				       (const u8 *) label, os_strlen(label),
    119 				       out, outlen);
    120 	if (hash_len == 48)
    121 		return hmac_sha384_kdf(secret, secret_len, NULL,
    122 				       (const u8 *) label, os_strlen(label),
    123 				       out, outlen);
    124 	if (hash_len == 64)
    125 		return hmac_sha512_kdf(secret, secret_len, NULL,
    126 				       (const u8 *) label, os_strlen(label),
    127 				       out, outlen);
    128 	return -1;
    129 }
    130 
    131 
    132 int dpp_hmac_vector(size_t hash_len, const u8 *key, size_t key_len,
    133 		    size_t num_elem, const u8 *addr[], const size_t *len,
    134 		    u8 *mac)
    135 {
    136 	if (hash_len == 32)
    137 		return hmac_sha256_vector(key, key_len, num_elem, addr, len,
    138 					  mac);
    139 	if (hash_len == 48)
    140 		return hmac_sha384_vector(key, key_len, num_elem, addr, len,
    141 					  mac);
    142 	if (hash_len == 64)
    143 		return hmac_sha512_vector(key, key_len, num_elem, addr, len,
    144 					  mac);
    145 	return -1;
    146 }
    147 
    148 
    149 static int dpp_hmac(size_t hash_len, const u8 *key, size_t key_len,
    150 		    const u8 *data, size_t data_len, u8 *mac)
    151 {
    152 	if (hash_len == 32)
    153 		return hmac_sha256(key, key_len, data, data_len, mac);
    154 	if (hash_len == 48)
    155 		return hmac_sha384(key, key_len, data, data_len, mac);
    156 	if (hash_len == 64)
    157 		return hmac_sha512(key, key_len, data, data_len, mac);
    158 	return -1;
    159 }
    160 
    161 
    162 #ifdef CONFIG_DPP2
    163 
    164 static int dpp_pbkdf2_f(size_t hash_len,
    165 			const u8 *password, size_t password_len,
    166 			const u8 *salt, size_t salt_len,
    167 			unsigned int iterations, unsigned int count, u8 *digest)
    168 {
    169 	unsigned char tmp[DPP_MAX_HASH_LEN], tmp2[DPP_MAX_HASH_LEN];
    170 	unsigned int i;
    171 	size_t j;
    172 	u8 count_buf[4];
    173 	const u8 *addr[2];
    174 	size_t len[2];
    175 
    176 	addr[0] = salt;
    177 	len[0] = salt_len;
    178 	addr[1] = count_buf;
    179 	len[1] = 4;
    180 
    181 	/* F(P, S, c, i) = U1 xor U2 xor ... Uc
    182 	 * U1 = PRF(P, S || i)
    183 	 * U2 = PRF(P, U1)
    184 	 * Uc = PRF(P, Uc-1)
    185 	 */
    186 
    187 	WPA_PUT_BE32(count_buf, count);
    188 	if (dpp_hmac_vector(hash_len, password, password_len, 2, addr, len,
    189 			    tmp))
    190 		return -1;
    191 	os_memcpy(digest, tmp, hash_len);
    192 
    193 	for (i = 1; i < iterations; i++) {
    194 		if (dpp_hmac(hash_len, password, password_len, tmp, hash_len,
    195 			     tmp2))
    196 			return -1;
    197 		os_memcpy(tmp, tmp2, hash_len);
    198 		for (j = 0; j < hash_len; j++)
    199 			digest[j] ^= tmp2[j];
    200 	}
    201 
    202 	return 0;
    203 }
    204 
    205 
    206 int dpp_pbkdf2(size_t hash_len, const u8 *password, size_t password_len,
    207 	       const u8 *salt, size_t salt_len, unsigned int iterations,
    208 	       u8 *buf, size_t buflen)
    209 {
    210 	unsigned int count = 0;
    211 	unsigned char *pos = buf;
    212 	size_t left = buflen, plen;
    213 	unsigned char digest[DPP_MAX_HASH_LEN];
    214 
    215 	while (left > 0) {
    216 		count++;
    217 		if (dpp_pbkdf2_f(hash_len, password, password_len,
    218 				 salt, salt_len, iterations, count, digest))
    219 			return -1;
    220 		plen = left > hash_len ? hash_len : left;
    221 		os_memcpy(pos, digest, plen);
    222 		pos += plen;
    223 		left -= plen;
    224 	}
    225 
    226 	return 0;
    227 }
    228 
    229 #endif /* CONFIG_DPP2 */
    230 
    231 
    232 struct crypto_ec_key * dpp_set_pubkey_point(struct crypto_ec_key *group_key,
    233 					    const u8 *buf, size_t len)
    234 {
    235 	int ike_group = crypto_ec_key_group(group_key);
    236 
    237 	if (len & 1)
    238 		return NULL;
    239 
    240 	if (ike_group < 0) {
    241 		wpa_printf(MSG_ERROR, "DPP: Could not get EC group");
    242 		return NULL;
    243 	}
    244 
    245 	return crypto_ec_key_set_pub(ike_group, buf, buf + len / 2, len / 2);
    246 }
    247 
    248 
    249 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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 *
    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 
    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
    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
    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 
    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 
    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 
   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 
   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 
   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 
   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 *
   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 *
   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 *
   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 
   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 
   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 
   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 *
   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 *
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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