xref: /freebsd/contrib/wpa/src/common/dpp_backup.c (revision 19261079b74319502c6ffa1249920079f0f69a72)
1 /*
2  * DPP configurator backup
3  * Copyright (c) 2019-2020, The Linux Foundation
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "utils/includes.h"
10 #include <openssl/opensslv.h>
11 #include <openssl/err.h>
12 
13 #include "utils/common.h"
14 #include "crypto/aes.h"
15 #include "crypto/aes_siv.h"
16 #include "tls/asn1.h"
17 #include "dpp.h"
18 #include "dpp_i.h"
19 
20 #ifdef CONFIG_DPP2
21 
22 #if OPENSSL_VERSION_NUMBER < 0x10100000L || \
23 	(defined(LIBRESSL_VERSION_NUMBER) && \
24 	 LIBRESSL_VERSION_NUMBER < 0x20700000L)
25 /* Compatibility wrappers for older versions. */
26 
27 static EC_KEY * EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
28 {
29 	if (pkey->type != EVP_PKEY_EC)
30 		return NULL;
31 	return pkey->pkey.ec;
32 }
33 
34 #endif
35 
36 
37 void dpp_free_asymmetric_key(struct dpp_asymmetric_key *key)
38 {
39 	while (key) {
40 		struct dpp_asymmetric_key *next = key->next;
41 
42 		EVP_PKEY_free(key->csign);
43 		EVP_PKEY_free(key->pp_key);
44 		str_clear_free(key->config_template);
45 		str_clear_free(key->connector_template);
46 		os_free(key);
47 		key = next;
48 	}
49 }
50 
51 
52 static struct wpabuf * dpp_build_conf_params(struct dpp_configurator *conf)
53 {
54 	struct wpabuf *buf, *priv_key = NULL;
55 	size_t len;
56 	/* TODO: proper template values */
57 	const char *conf_template = "{\"wi-fi_tech\":\"infra\",\"discovery\":{\"ssid\":\"test\"},\"cred\":{\"akm\":\"dpp\"}}";
58 	const char *connector_template = NULL;
59 	EC_KEY *eckey;
60 	unsigned char *der = NULL;
61 	int der_len;
62 
63 	if (!conf->pp_key)
64 		return NULL;
65 	eckey = EVP_PKEY_get0_EC_KEY(conf->pp_key);
66 	if (!eckey)
67 		return NULL;
68 
69 	EC_KEY_set_enc_flags(eckey, EC_PKEY_NO_PUBKEY);
70 	der_len = i2d_ECPrivateKey(eckey, &der);
71 	if (der_len > 0)
72 		priv_key = wpabuf_alloc_copy(der, der_len);
73 	OPENSSL_free(der);
74 	if (!priv_key)
75 		goto fail;
76 
77 	len = 100 + os_strlen(conf_template);
78 	if (connector_template)
79 		len += os_strlen(connector_template);
80 	if (priv_key)
81 		len += wpabuf_len(priv_key);
82 	buf = wpabuf_alloc(len);
83 	if (!buf)
84 		goto fail;
85 
86 	/*
87 	 * DPPConfigurationParameters ::= SEQUENCE {
88 	 *    privacyProtectionKey      PrivateKey,
89 	 *    configurationTemplate	UTF8String,
90 	 *    connectorTemplate		UTF8String OPTIONAL}
91 	 */
92 
93 	/* PrivateKey ::= OCTET STRING */
94 	asn1_put_octet_string(buf, priv_key);
95 
96 	asn1_put_utf8string(buf, conf_template);
97 	if (connector_template)
98 		asn1_put_utf8string(buf, connector_template);
99 	wpabuf_clear_free(priv_key);
100 	return asn1_encaps(buf, ASN1_CLASS_UNIVERSAL, ASN1_TAG_SEQUENCE);
101 fail:
102 	wpabuf_clear_free(priv_key);
103 	return NULL;
104 }
105 
106 
107 static struct wpabuf * dpp_build_attribute(struct dpp_configurator *conf)
108 {
109 	struct wpabuf *conf_params, *attr;
110 
111 	/*
112 	 * aa-DPPConfigurationParameters ATTRIBUTE ::=
113 	 * { TYPE DPPConfigurationParameters IDENTIFIED BY id-DPPConfigParams }
114 	 *
115 	 * Attribute ::= SEQUENCE {
116 	 *    type OBJECT IDENTIFIER,
117 	 *    values SET SIZE(1..MAX) OF Type
118 	 */
119 	conf_params = dpp_build_conf_params(conf);
120 	conf_params = asn1_encaps(conf_params, ASN1_CLASS_UNIVERSAL,
121 				  ASN1_TAG_SET);
122 	if (!conf_params)
123 		return NULL;
124 
125 	attr = wpabuf_alloc(100 + wpabuf_len(conf_params));
126 	if (!attr) {
127 		wpabuf_clear_free(conf_params);
128 		return NULL;
129 	}
130 
131 	asn1_put_oid(attr, &asn1_dpp_config_params_oid);
132 	wpabuf_put_buf(attr, conf_params);
133 	wpabuf_clear_free(conf_params);
134 
135 	return asn1_encaps(attr, ASN1_CLASS_UNIVERSAL, ASN1_TAG_SEQUENCE);
136 }
137 
138 
139 static struct wpabuf * dpp_build_key_alg(const struct dpp_curve_params *curve)
140 {
141 	const struct asn1_oid *oid;
142 	struct wpabuf *params, *res;
143 
144 	switch (curve->ike_group) {
145 	case 19:
146 		oid = &asn1_prime256v1_oid;
147 		break;
148 	case 20:
149 		oid = &asn1_secp384r1_oid;
150 		break;
151 	case 21:
152 		oid = &asn1_secp521r1_oid;
153 		break;
154 	case 28:
155 		oid = &asn1_brainpoolP256r1_oid;
156 		break;
157 	case 29:
158 		oid = &asn1_brainpoolP384r1_oid;
159 		break;
160 	case 30:
161 		oid = &asn1_brainpoolP512r1_oid;
162 		break;
163 	default:
164 		return NULL;
165 	}
166 
167 	params = wpabuf_alloc(20);
168 	if (!params)
169 		return NULL;
170 	asn1_put_oid(params, oid); /* namedCurve */
171 
172 	res = asn1_build_alg_id(&asn1_ec_public_key_oid, params);
173 	wpabuf_free(params);
174 	return res;
175 }
176 
177 
178 static struct wpabuf * dpp_build_key_pkg(struct dpp_authentication *auth)
179 {
180 	struct wpabuf *key = NULL, *attr, *alg, *priv_key = NULL;
181 	EC_KEY *eckey;
182 	unsigned char *der = NULL;
183 	int der_len;
184 
185 	eckey = EVP_PKEY_get0_EC_KEY(auth->conf->csign);
186 	if (!eckey)
187 		return NULL;
188 
189 	EC_KEY_set_enc_flags(eckey, EC_PKEY_NO_PUBKEY);
190 	der_len = i2d_ECPrivateKey(eckey, &der);
191 	if (der_len > 0)
192 		priv_key = wpabuf_alloc_copy(der, der_len);
193 	OPENSSL_free(der);
194 
195 	alg = dpp_build_key_alg(auth->conf->curve);
196 
197 	/* Attributes ::= SET OF Attribute { { OneAsymmetricKeyAttributes } } */
198 	attr = dpp_build_attribute(auth->conf);
199 	attr = asn1_encaps(attr, ASN1_CLASS_UNIVERSAL, ASN1_TAG_SET);
200 	if (!priv_key || !attr || !alg)
201 		goto fail;
202 
203 	/*
204 	 * OneAsymmetricKey ::= SEQUENCE {
205 	 *    version			Version,
206 	 *    privateKeyAlgorithm	PrivateKeyAlgorithmIdentifier,
207 	 *    privateKey		PrivateKey,
208 	 *    attributes		[0] Attributes OPTIONAL,
209 	 *    ...,
210 	 *    [[2: publicKey		[1] BIT STRING OPTIONAL ]],
211 	 *    ...
212 	 * }
213 	 */
214 
215 	key = wpabuf_alloc(100 + wpabuf_len(alg) + wpabuf_len(priv_key) +
216 			   wpabuf_len(attr));
217 	if (!key)
218 		goto fail;
219 
220 	asn1_put_integer(key, 0); /* version = v1(0) */
221 
222 	/* PrivateKeyAlgorithmIdentifier */
223 	wpabuf_put_buf(key, alg);
224 
225 	/* PrivateKey ::= OCTET STRING */
226 	asn1_put_octet_string(key, priv_key);
227 
228 	/* [0] Attributes OPTIONAL */
229 	asn1_put_hdr(key, ASN1_CLASS_CONTEXT_SPECIFIC, 1, 0, wpabuf_len(attr));
230 	wpabuf_put_buf(key, attr);
231 
232 fail:
233 	wpabuf_clear_free(attr);
234 	wpabuf_clear_free(priv_key);
235 	wpabuf_free(alg);
236 
237 	/*
238 	 * DPPAsymmetricKeyPackage ::= AsymmetricKeyPackage
239 	 *
240 	 * AsymmetricKeyPackage ::= SEQUENCE SIZE (1..MAX) OF OneAsymmetricKey
241 	 *
242 	 * OneAsymmetricKey ::= SEQUENCE
243 	 */
244 	return asn1_encaps(asn1_encaps(key,
245 				       ASN1_CLASS_UNIVERSAL, ASN1_TAG_SEQUENCE),
246 			   ASN1_CLASS_UNIVERSAL, ASN1_TAG_SEQUENCE);
247 }
248 
249 
250 static struct wpabuf * dpp_build_pbkdf2_alg_id(const struct wpabuf *salt,
251 					       size_t hash_len)
252 {
253 	struct wpabuf *params = NULL, *buf = NULL, *prf = NULL;
254 	const struct asn1_oid *oid;
255 
256 	/*
257 	 * PBKDF2-params ::= SEQUENCE {
258 	 *    salt CHOICE {
259 	 *       specified OCTET STRING,
260 	 *       otherSource AlgorithmIdentifier}
261 	 *    iterationCount INTEGER (1..MAX),
262 	 *    keyLength INTEGER (1..MAX),
263 	 *    prf AlgorithmIdentifier}
264 	 *
265 	 * salt is an 64 octet value, iterationCount is 1000, keyLength is based
266 	 * on Configurator signing key length, prf is
267 	 * id-hmacWithSHA{256,384,512} based on Configurator signing key.
268 	 */
269 
270 	if (hash_len == 32)
271 		oid = &asn1_pbkdf2_hmac_sha256_oid;
272 	else if (hash_len == 48)
273 		oid = &asn1_pbkdf2_hmac_sha384_oid;
274 	else if (hash_len == 64)
275 		oid = &asn1_pbkdf2_hmac_sha512_oid;
276 	else
277 		goto fail;
278 	prf = asn1_build_alg_id(oid, NULL);
279 	if (!prf)
280 		goto fail;
281 	params = wpabuf_alloc(100 + wpabuf_len(salt) + wpabuf_len(prf));
282 	if (!params)
283 		goto fail;
284 	asn1_put_octet_string(params, salt); /* salt.specified */
285 	asn1_put_integer(params, 1000); /* iterationCount */
286 	asn1_put_integer(params, hash_len); /* keyLength */
287 	wpabuf_put_buf(params, prf);
288 	params = asn1_encaps(params, ASN1_CLASS_UNIVERSAL, ASN1_TAG_SEQUENCE);
289 	if (!params)
290 		goto fail;
291 	buf = asn1_build_alg_id(&asn1_pbkdf2_oid, params);
292 fail:
293 	wpabuf_free(params);
294 	wpabuf_free(prf);
295 	return buf;
296 }
297 
298 
299 static struct wpabuf *
300 dpp_build_pw_recipient_info(struct dpp_authentication *auth, size_t hash_len,
301 			    const struct wpabuf *cont_enc_key)
302 {
303 	struct wpabuf *pwri = NULL, *enc_key = NULL, *key_der_alg = NULL,
304 		*key_enc_alg = NULL, *salt;
305 	u8 kek[DPP_MAX_HASH_LEN];
306 	u8 key[DPP_MAX_HASH_LEN];
307 	size_t key_len;
308 	int res;
309 
310 	salt = wpabuf_alloc(64);
311 	if (!salt || os_get_random(wpabuf_put(salt, 64), 64) < 0)
312 		goto fail;
313 	wpa_hexdump_buf(MSG_DEBUG, "DPP: PBKDF2 salt", salt);
314 
315 	key_len = auth->curve->hash_len;
316 	/* password = HKDF-Expand(bk, "Enveloped Data Password", length) */
317 	res = dpp_hkdf_expand(key_len, auth->bk, key_len,
318 			      "Enveloped Data Password", key, key_len);
319 	if (res < 0)
320 		goto fail;
321 	wpa_hexdump_key(MSG_DEBUG, "DPP: PBKDF2 key", key, key_len);
322 
323 	if (dpp_pbkdf2(hash_len, key, key_len, wpabuf_head(salt), 64, 1000,
324 		       kek, hash_len)) {
325 		wpa_printf(MSG_DEBUG, "DPP: PBKDF2 failed");
326 		goto fail;
327 	}
328 	wpa_hexdump_key(MSG_DEBUG, "DPP: key-encryption key from PBKDF2",
329 			kek, hash_len);
330 
331 	enc_key = wpabuf_alloc(hash_len + AES_BLOCK_SIZE);
332 	if (!enc_key ||
333 	    aes_siv_encrypt(kek, hash_len, wpabuf_head(cont_enc_key),
334 			    wpabuf_len(cont_enc_key), 0, NULL, NULL,
335 			    wpabuf_put(enc_key, hash_len + AES_BLOCK_SIZE)) < 0)
336 		goto fail;
337 	wpa_hexdump_buf(MSG_DEBUG, "DPP: encryptedKey", enc_key);
338 
339 	/*
340 	 * PasswordRecipientInfo ::= SEQUENCE {
341 	 *    version			CMSVersion,
342 	 *    keyDerivationAlgorithm [0] KeyDerivationAlgorithmIdentifier OPTIONAL,
343 	 *    keyEncryptionAlgorithm	KeyEncryptionAlgorithmIdentifier,
344 	 *    encryptedKey		EncryptedKey}
345 	 *
346 	 * version is 0, keyDerivationAlgorithm is id-PKBDF2, and the
347 	 * parameters contains PBKDF2-params SEQUENCE.
348 	 */
349 
350 	key_der_alg = dpp_build_pbkdf2_alg_id(salt, hash_len);
351 	key_enc_alg = asn1_build_alg_id(&asn1_aes_siv_cmac_aead_256_oid, NULL);
352 	if (!key_der_alg || !key_enc_alg)
353 		goto fail;
354 	pwri = wpabuf_alloc(100 + wpabuf_len(key_der_alg) +
355 			    wpabuf_len(key_enc_alg) + wpabuf_len(enc_key));
356 	if (!pwri)
357 		goto fail;
358 
359 	/* version = 0 */
360 	asn1_put_integer(pwri, 0);
361 
362 	/* [0] KeyDerivationAlgorithmIdentifier */
363 	asn1_put_hdr(pwri, ASN1_CLASS_CONTEXT_SPECIFIC, 1, 0,
364 		     wpabuf_len(key_der_alg));
365 	wpabuf_put_buf(pwri, key_der_alg);
366 
367 	/* KeyEncryptionAlgorithmIdentifier */
368 	wpabuf_put_buf(pwri, key_enc_alg);
369 
370 	/* EncryptedKey ::= OCTET STRING */
371 	asn1_put_octet_string(pwri, enc_key);
372 
373 fail:
374 	wpabuf_clear_free(key_der_alg);
375 	wpabuf_free(key_enc_alg);
376 	wpabuf_free(enc_key);
377 	wpabuf_free(salt);
378 	forced_memzero(kek, sizeof(kek));
379 	return asn1_encaps(pwri, ASN1_CLASS_UNIVERSAL, ASN1_TAG_SEQUENCE);
380 }
381 
382 
383 static struct wpabuf *
384 dpp_build_recipient_info(struct dpp_authentication *auth, size_t hash_len,
385 			 const struct wpabuf *cont_enc_key)
386 {
387 	struct wpabuf *pwri;
388 
389 	/*
390 	 * RecipientInfo ::= CHOICE {
391 	 *    ktri		KeyTransRecipientInfo,
392 	 *    kari	[1]	KeyAgreeRecipientInfo,
393 	 *    kekri	[2]	KEKRecipientInfo,
394 	 *    pwri	[3]	PasswordRecipientInfo,
395 	 *    ori	[4]	OtherRecipientInfo}
396 	 *
397 	 * Shall always use the pwri CHOICE.
398 	 */
399 
400 	pwri = dpp_build_pw_recipient_info(auth, hash_len, cont_enc_key);
401 	return asn1_encaps(pwri, ASN1_CLASS_CONTEXT_SPECIFIC, 3);
402 }
403 
404 
405 static struct wpabuf *
406 dpp_build_enc_cont_info(struct dpp_authentication *auth, size_t hash_len,
407 			const struct wpabuf *cont_enc_key)
408 {
409 	struct wpabuf *key_pkg, *enc_cont_info = NULL, *enc_cont = NULL,
410 		*enc_alg;
411 	const struct asn1_oid *oid;
412 	size_t enc_cont_len;
413 
414 	/*
415 	 * EncryptedContentInfo ::= SEQUENCE {
416 	 *    contentType			ContentType,
417 	 *    contentEncryptionAlgorithm  ContentEncryptionAlgorithmIdentifier,
418 	 *    encryptedContent	[0] IMPLICIT	EncryptedContent OPTIONAL}
419 	 */
420 
421 	if (hash_len == 32)
422 		oid = &asn1_aes_siv_cmac_aead_256_oid;
423 	else if (hash_len == 48)
424 		oid = &asn1_aes_siv_cmac_aead_384_oid;
425 	else if (hash_len == 64)
426 		oid = &asn1_aes_siv_cmac_aead_512_oid;
427 	else
428 		return NULL;
429 
430 	key_pkg = dpp_build_key_pkg(auth);
431 	enc_alg = asn1_build_alg_id(oid, NULL);
432 	if (!key_pkg || !enc_alg)
433 		goto fail;
434 
435 	wpa_hexdump_buf_key(MSG_MSGDUMP, "DPP: DPPAsymmetricKeyPackage",
436 			    key_pkg);
437 
438 	enc_cont_len = wpabuf_len(key_pkg) + AES_BLOCK_SIZE;
439 	enc_cont = wpabuf_alloc(enc_cont_len);
440 	if (!enc_cont ||
441 	    aes_siv_encrypt(wpabuf_head(cont_enc_key), wpabuf_len(cont_enc_key),
442 			    wpabuf_head(key_pkg), wpabuf_len(key_pkg),
443 			    0, NULL, NULL,
444 			    wpabuf_put(enc_cont, enc_cont_len)) < 0)
445 		goto fail;
446 
447 	enc_cont_info = wpabuf_alloc(100 + wpabuf_len(enc_alg) +
448 				     wpabuf_len(enc_cont));
449 	if (!enc_cont_info)
450 		goto fail;
451 
452 	/* ContentType ::= OBJECT IDENTIFIER */
453 	asn1_put_oid(enc_cont_info, &asn1_dpp_asymmetric_key_package_oid);
454 
455 	/* ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier */
456 	wpabuf_put_buf(enc_cont_info, enc_alg);
457 
458 	/* encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL
459 	 * EncryptedContent ::= OCTET STRING */
460 	asn1_put_hdr(enc_cont_info, ASN1_CLASS_CONTEXT_SPECIFIC, 0, 0,
461 		     wpabuf_len(enc_cont));
462 	wpabuf_put_buf(enc_cont_info, enc_cont);
463 
464 fail:
465 	wpabuf_clear_free(key_pkg);
466 	wpabuf_free(enc_cont);
467 	wpabuf_free(enc_alg);
468 	return enc_cont_info;
469 }
470 
471 
472 static struct wpabuf * dpp_gen_random(size_t len)
473 {
474 	struct wpabuf *key;
475 
476 	key = wpabuf_alloc(len);
477 	if (!key || os_get_random(wpabuf_put(key, len), len) < 0) {
478 		wpabuf_free(key);
479 		key = NULL;
480 	}
481 	wpa_hexdump_buf_key(MSG_DEBUG, "DPP: content-encryption key", key);
482 	return key;
483 }
484 
485 
486 struct wpabuf * dpp_build_enveloped_data(struct dpp_authentication *auth)
487 {
488 	struct wpabuf *env = NULL;
489 	struct wpabuf *recipient_info = NULL, *enc_cont_info = NULL;
490 	struct wpabuf *cont_enc_key = NULL;
491 	size_t hash_len;
492 
493 	if (!auth->conf) {
494 		wpa_printf(MSG_DEBUG,
495 			   "DPP: No Configurator instance selected for the session - cannot build DPPEnvelopedData");
496 		return NULL;
497 	}
498 
499 	if (!auth->provision_configurator) {
500 		wpa_printf(MSG_DEBUG,
501 			   "DPP: Configurator provisioning not allowed");
502 		return NULL;
503 	}
504 
505 	wpa_printf(MSG_DEBUG, "DPP: Building DPPEnvelopedData");
506 
507 	hash_len = auth->conf->curve->hash_len;
508 	cont_enc_key = dpp_gen_random(hash_len);
509 	if (!cont_enc_key)
510 		goto fail;
511 	recipient_info = dpp_build_recipient_info(auth, hash_len, cont_enc_key);
512 	enc_cont_info = dpp_build_enc_cont_info(auth, hash_len, cont_enc_key);
513 	if (!recipient_info || !enc_cont_info)
514 		goto fail;
515 
516 	env = wpabuf_alloc(wpabuf_len(recipient_info) +
517 			   wpabuf_len(enc_cont_info) +
518 			   100);
519 	if (!env)
520 		goto fail;
521 
522 	/*
523 	 * DPPEnvelopedData ::= EnvelopedData
524 	 *
525 	 * EnvelopedData ::= SEQUENCE {
526 	 *    version			CMSVersion,
527 	 *    originatorInfo	[0]	IMPLICIT OriginatorInfo OPTIONAL,
528 	 *    recipientInfos		RecipientInfos,
529 	 *    encryptedContentInfo	EncryptedContentInfo,
530 	 *    unprotectedAttrs  [1] IMPLICIT	UnprotectedAttributes OPTIONAL}
531 	 *
532 	 * For DPP, version is 3, both originatorInfo and
533 	 * unprotectedAttrs are omitted, and recipientInfos contains a single
534 	 * RecipientInfo.
535 	 */
536 
537 	/* EnvelopedData.version = 3 */
538 	asn1_put_integer(env, 3);
539 
540 	/* RecipientInfos ::= SET SIZE (1..MAX) OF RecipientInfo */
541 	asn1_put_set(env, recipient_info);
542 
543 	/* EncryptedContentInfo ::= SEQUENCE */
544 	asn1_put_sequence(env, enc_cont_info);
545 
546 	env = asn1_encaps(env, ASN1_CLASS_UNIVERSAL, ASN1_TAG_SEQUENCE);
547 	wpa_hexdump_buf(MSG_MSGDUMP, "DPP: DPPEnvelopedData", env);
548 out:
549 	wpabuf_clear_free(cont_enc_key);
550 	wpabuf_clear_free(recipient_info);
551 	wpabuf_free(enc_cont_info);
552 	return env;
553 fail:
554 	wpabuf_free(env);
555 	env = NULL;
556 	goto out;
557 }
558 
559 
560 struct dpp_enveloped_data {
561 	const u8 *enc_cont;
562 	size_t enc_cont_len;
563 	const u8 *enc_key;
564 	size_t enc_key_len;
565 	const u8 *salt;
566 	size_t pbkdf2_key_len;
567 	size_t prf_hash_len;
568 };
569 
570 
571 static int dpp_parse_recipient_infos(const u8 *pos, size_t len,
572 				     struct dpp_enveloped_data *data)
573 {
574 	struct asn1_hdr hdr;
575 	const u8 *end = pos + len;
576 	const u8 *next, *e_end;
577 	struct asn1_oid oid;
578 	int val;
579 	const u8 *params;
580 	size_t params_len;
581 
582 	wpa_hexdump(MSG_MSGDUMP, "DPP: RecipientInfos", pos, len);
583 
584 	/*
585 	 * RecipientInfo ::= CHOICE {
586 	 *    ktri		KeyTransRecipientInfo,
587 	 *    kari	[1]	KeyAgreeRecipientInfo,
588 	 *    kekri	[2]	KEKRecipientInfo,
589 	 *    pwri	[3]	PasswordRecipientInfo,
590 	 *    ori	[4]	OtherRecipientInfo}
591 	 *
592 	 * Shall always use the pwri CHOICE.
593 	 */
594 
595 	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
596 	    !asn1_is_cs_tag(&hdr, 3)) {
597 		asn1_unexpected(&hdr, "DPP: Expected CHOICE [3] (pwri)");
598 		return -1;
599 	}
600 	wpa_hexdump(MSG_MSGDUMP, "DPP: PasswordRecipientInfo",
601 		    hdr.payload, hdr.length);
602 	pos = hdr.payload;
603 	end = pos + hdr.length;
604 
605 	/*
606 	 * PasswordRecipientInfo ::= SEQUENCE {
607 	 *    version			CMSVersion,
608 	 *    keyDerivationAlgorithm [0] KeyDerivationAlgorithmIdentifier OPTIONAL,
609 	 *    keyEncryptionAlgorithm	KeyEncryptionAlgorithmIdentifier,
610 	 *    encryptedKey		EncryptedKey}
611 	 *
612 	 * version is 0, keyDerivationAlgorithm is id-PKBDF2, and the
613 	 * parameters contains PBKDF2-params SEQUENCE.
614 	 */
615 
616 	if (asn1_get_sequence(pos, end - pos, &hdr, &end) < 0)
617 		return -1;
618 	pos = hdr.payload;
619 
620 	if (asn1_get_integer(pos, end - pos, &val, &pos) < 0)
621 		return -1;
622 	if (val != 0) {
623 		wpa_printf(MSG_DEBUG, "DPP: pwri.version != 0");
624 		return -1;
625 	}
626 
627 	wpa_hexdump(MSG_MSGDUMP, "DPP: Remaining PasswordRecipientInfo after version",
628 		    pos, end - pos);
629 
630 	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
631 	    !asn1_is_cs_tag(&hdr, 0)) {
632 		asn1_unexpected(&hdr,
633 				"DPP: Expected keyDerivationAlgorithm [0]");
634 		return -1;
635 	}
636 	pos = hdr.payload;
637 	e_end = pos + hdr.length;
638 
639 	/* KeyDerivationAlgorithmIdentifier ::= AlgorithmIdentifier */
640 	if (asn1_get_alg_id(pos, e_end - pos, &oid, &params, &params_len,
641 			    &next) < 0)
642 		return -1;
643 	if (!asn1_oid_equal(&oid, &asn1_pbkdf2_oid)) {
644 		char buf[80];
645 
646 		asn1_oid_to_str(&oid, buf, sizeof(buf));
647 		wpa_printf(MSG_DEBUG,
648 			   "DPP: Unexpected KeyDerivationAlgorithmIdentifier %s",
649 			   buf);
650 		return -1;
651 	}
652 
653 	/*
654 	 * PBKDF2-params ::= SEQUENCE {
655 	 *    salt CHOICE {
656 	 *       specified OCTET STRING,
657 	 *       otherSource AlgorithmIdentifier}
658 	 *    iterationCount INTEGER (1..MAX),
659 	 *    keyLength INTEGER (1..MAX),
660 	 *    prf AlgorithmIdentifier}
661 	 *
662 	 * salt is an 64 octet value, iterationCount is 1000, keyLength is based
663 	 * on Configurator signing key length, prf is
664 	 * id-hmacWithSHA{256,384,512} based on Configurator signing key.
665 	 */
666 	if (!params ||
667 	    asn1_get_sequence(params, params_len, &hdr, &e_end) < 0)
668 		return -1;
669 	pos = hdr.payload;
670 
671 	if (asn1_get_next(pos, e_end - pos, &hdr) < 0 ||
672 	    !asn1_is_octetstring(&hdr)) {
673 		asn1_unexpected(&hdr,
674 				"DPP: Expected OCTETSTRING (salt.specified)");
675 		return -1;
676 	}
677 	wpa_hexdump(MSG_MSGDUMP, "DPP: salt.specified",
678 		    hdr.payload, hdr.length);
679 	if (hdr.length != 64) {
680 		wpa_printf(MSG_DEBUG, "DPP: Unexpected salt length %u",
681 			   hdr.length);
682 		return -1;
683 	}
684 	data->salt = hdr.payload;
685 	pos = hdr.payload + hdr.length;
686 
687 	if (asn1_get_integer(pos, e_end - pos, &val, &pos) < 0)
688 		return -1;
689 	if (val != 1000) {
690 		wpa_printf(MSG_DEBUG, "DPP: Unexpected iterationCount %d", val);
691 		return -1;
692 	}
693 
694 	if (asn1_get_integer(pos, e_end - pos, &val, &pos) < 0)
695 		return -1;
696 	if (val != 32 && val != 48 && val != 64) {
697 		wpa_printf(MSG_DEBUG, "DPP: Unexpected keyLength %d", val);
698 		return -1;
699 	}
700 	data->pbkdf2_key_len = val;
701 
702 	if (asn1_get_sequence(pos, e_end - pos, &hdr, NULL) < 0 ||
703 	    asn1_get_oid(hdr.payload, hdr.length, &oid, &pos) < 0) {
704 		wpa_printf(MSG_DEBUG, "DPP: Could not parse prf");
705 		return -1;
706 	}
707 	if (asn1_oid_equal(&oid, &asn1_pbkdf2_hmac_sha256_oid)) {
708 		data->prf_hash_len = 32;
709 	} else if (asn1_oid_equal(&oid, &asn1_pbkdf2_hmac_sha384_oid)) {
710 		data->prf_hash_len = 48;
711 	} else if (asn1_oid_equal(&oid, &asn1_pbkdf2_hmac_sha512_oid)) {
712 		data->prf_hash_len = 64;
713 	} else {
714 		char buf[80];
715 
716 		asn1_oid_to_str(&oid, buf, sizeof(buf));
717 		wpa_printf(MSG_DEBUG, "DPP: Unexpected PBKDF2-params.prf %s",
718 			   buf);
719 		return -1;
720 	}
721 
722 	pos = next;
723 
724 	/* keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier
725 	 *
726 	 * KeyEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
727 	 *
728 	 * id-alg-AES-SIV-CMAC-aed-256, id-alg-AES-SIV-CMAC-aed-384, or
729 	 * id-alg-AES-SIV-CMAC-aed-512. */
730 	if (asn1_get_alg_id(pos, end - pos, &oid, NULL, NULL, &pos) < 0)
731 		return -1;
732 	if (!asn1_oid_equal(&oid, &asn1_aes_siv_cmac_aead_256_oid) &&
733 	    !asn1_oid_equal(&oid, &asn1_aes_siv_cmac_aead_384_oid) &&
734 	    !asn1_oid_equal(&oid, &asn1_aes_siv_cmac_aead_512_oid)) {
735 		char buf[80];
736 
737 		asn1_oid_to_str(&oid, buf, sizeof(buf));
738 		wpa_printf(MSG_DEBUG,
739 			   "DPP: Unexpected KeyEncryptionAlgorithmIdentifier %s",
740 			   buf);
741 		return -1;
742 	}
743 
744 	/*
745 	 * encryptedKey EncryptedKey
746 	 *
747 	 * EncryptedKey ::= OCTET STRING
748 	 */
749 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
750 	    !asn1_is_octetstring(&hdr)) {
751 		asn1_unexpected(&hdr,
752 				"DPP: Expected OCTETSTRING (pwri.encryptedKey)");
753 		return -1;
754 	}
755 	wpa_hexdump(MSG_MSGDUMP, "DPP: pwri.encryptedKey",
756 		    hdr.payload, hdr.length);
757 	data->enc_key = hdr.payload;
758 	data->enc_key_len = hdr.length;
759 
760 	return 0;
761 }
762 
763 
764 static int dpp_parse_encrypted_content_info(const u8 *pos, const u8 *end,
765 					    struct dpp_enveloped_data *data)
766 {
767 	struct asn1_hdr hdr;
768 	struct asn1_oid oid;
769 
770 	/*
771 	 * EncryptedContentInfo ::= SEQUENCE {
772 	 *    contentType			ContentType,
773 	 *    contentEncryptionAlgorithm  ContentEncryptionAlgorithmIdentifier,
774 	 *    encryptedContent	[0] IMPLICIT	EncryptedContent OPTIONAL}
775 	 */
776 	if (asn1_get_sequence(pos, end - pos, &hdr, &pos) < 0)
777 		return -1;
778 	wpa_hexdump(MSG_MSGDUMP, "DPP: EncryptedContentInfo",
779 		    hdr.payload, hdr.length);
780 	if (pos < end) {
781 		wpa_hexdump(MSG_DEBUG,
782 			    "DPP: Unexpected extra data after EncryptedContentInfo",
783 			    pos, end - pos);
784 		return -1;
785 	}
786 
787 	end = pos;
788 	pos = hdr.payload;
789 
790 	/* ContentType ::= OBJECT IDENTIFIER */
791 	if (asn1_get_oid(pos, end - pos, &oid, &pos) < 0) {
792 		wpa_printf(MSG_DEBUG, "DPP: Could not parse ContentType");
793 		return -1;
794 	}
795 	if (!asn1_oid_equal(&oid, &asn1_dpp_asymmetric_key_package_oid)) {
796 		char buf[80];
797 
798 		asn1_oid_to_str(&oid, buf, sizeof(buf));
799 		wpa_printf(MSG_DEBUG, "DPP: Unexpected ContentType %s", buf);
800 		return -1;
801 	}
802 
803 	/* ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier */
804 	if (asn1_get_alg_id(pos, end - pos, &oid, NULL, NULL, &pos) < 0)
805 		return -1;
806 	if (!asn1_oid_equal(&oid, &asn1_aes_siv_cmac_aead_256_oid) &&
807 	    !asn1_oid_equal(&oid, &asn1_aes_siv_cmac_aead_384_oid) &&
808 	    !asn1_oid_equal(&oid, &asn1_aes_siv_cmac_aead_512_oid)) {
809 		char buf[80];
810 
811 		asn1_oid_to_str(&oid, buf, sizeof(buf));
812 		wpa_printf(MSG_DEBUG,
813 			   "DPP: Unexpected ContentEncryptionAlgorithmIdentifier %s",
814 			   buf);
815 		return -1;
816 	}
817 	/* ignore optional parameters */
818 
819 	/* encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL
820 	 * EncryptedContent ::= OCTET STRING */
821 	if (asn1_get_next(pos, end - pos, &hdr) < 0 || hdr.constructed ||
822 	    !asn1_is_cs_tag(&hdr, 0)) {
823 		asn1_unexpected(&hdr,
824 				"DPP: Expected [0] IMPLICIT (EncryptedContent)");
825 		return -1;
826 	}
827 	wpa_hexdump(MSG_MSGDUMP, "DPP: EncryptedContent",
828 		    hdr.payload, hdr.length);
829 	data->enc_cont = hdr.payload;
830 	data->enc_cont_len = hdr.length;
831 	return 0;
832 }
833 
834 
835 static int dpp_parse_enveloped_data(const u8 *env_data, size_t env_data_len,
836 				    struct dpp_enveloped_data *data)
837 {
838 	struct asn1_hdr hdr;
839 	const u8 *pos, *end;
840 	int val;
841 
842 	os_memset(data, 0, sizeof(*data));
843 
844 	/*
845 	 * DPPEnvelopedData ::= EnvelopedData
846 	 *
847 	 * EnvelopedData ::= SEQUENCE {
848 	 *    version			CMSVersion,
849 	 *    originatorInfo	[0]	IMPLICIT OriginatorInfo OPTIONAL,
850 	 *    recipientInfos		RecipientInfos,
851 	 *    encryptedContentInfo	EncryptedContentInfo,
852 	 *    unprotectedAttrs  [1] IMPLICIT	UnprotectedAttributes OPTIONAL}
853 	 *
854 	 * CMSVersion ::= INTEGER
855 	 *
856 	 * RecipientInfos ::= SET SIZE (1..MAX) OF RecipientInfo
857 	 *
858 	 * For DPP, version is 3, both originatorInfo and
859 	 * unprotectedAttrs are omitted, and recipientInfos contains a single
860 	 * RecipientInfo.
861 	 */
862 	if (asn1_get_sequence(env_data, env_data_len, &hdr, &end) < 0)
863 		return -1;
864 	pos = hdr.payload;
865 	if (end < env_data + env_data_len) {
866 		wpa_hexdump(MSG_DEBUG,
867 			    "DPP: Unexpected extra data after DPPEnvelopedData",
868 			    end, env_data + env_data_len - end);
869 		return -1;
870 	}
871 
872 	if (asn1_get_integer(pos, end - pos, &val, &pos) < 0)
873 		return -1;
874 	if (val != 3) {
875 		wpa_printf(MSG_DEBUG, "DPP: EnvelopedData.version != 3");
876 		return -1;
877 	}
878 
879 	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !asn1_is_set(&hdr)) {
880 		asn1_unexpected(&hdr,
881 				"DPP: Expected SET (RecipientInfos)");
882 		return -1;
883 	}
884 
885 	if (dpp_parse_recipient_infos(hdr.payload, hdr.length, data) < 0)
886 		return -1;
887 	return dpp_parse_encrypted_content_info(hdr.payload + hdr.length, end,
888 						data);
889 }
890 
891 
892 static struct dpp_asymmetric_key *
893 dpp_parse_one_asymmetric_key(const u8 *buf, size_t len)
894 {
895 	struct asn1_hdr hdr;
896 	const u8 *pos = buf, *end = buf + len, *next;
897 	int val;
898 	const u8 *params;
899 	size_t params_len;
900 	struct asn1_oid oid;
901 	char txt[80];
902 	struct dpp_asymmetric_key *key;
903 	EC_KEY *eckey;
904 
905 	wpa_hexdump_key(MSG_MSGDUMP, "DPP: OneAsymmetricKey", buf, len);
906 
907 	key = os_zalloc(sizeof(*key));
908 	if (!key)
909 		return NULL;
910 
911 	/*
912 	 * OneAsymmetricKey ::= SEQUENCE {
913 	 *    version			Version,
914 	 *    privateKeyAlgorithm	PrivateKeyAlgorithmIdentifier,
915 	 *    privateKey		PrivateKey,
916 	 *    attributes		[0] Attributes OPTIONAL,
917 	 *    ...,
918 	 *    [[2: publicKey		[1] BIT STRING OPTIONAL ]],
919 	 *    ...
920 	 * }
921 	 */
922 	if (asn1_get_sequence(pos, end - pos, &hdr, &end) < 0)
923 		goto fail;
924 	pos = hdr.payload;
925 
926 	/* Version ::= INTEGER { v1(0), v2(1) } (v1, ..., v2) */
927 	if (asn1_get_integer(pos, end - pos, &val, &pos) < 0)
928 		goto fail;
929 	if (val != 0 && val != 1) {
930 		wpa_printf(MSG_DEBUG,
931 			   "DPP: Unsupported DPPAsymmetricKeyPackage version %d",
932 			   val);
933 		goto fail;
934 	}
935 
936 	/* PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier */
937 	if (asn1_get_alg_id(pos, end - pos, &oid, &params, &params_len,
938 			    &pos) < 0)
939 		goto fail;
940 	if (!asn1_oid_equal(&oid, &asn1_ec_public_key_oid)) {
941 		asn1_oid_to_str(&oid, txt, sizeof(txt));
942 		wpa_printf(MSG_DEBUG,
943 			   "DPP: Unsupported PrivateKeyAlgorithmIdentifier %s",
944 			   txt);
945 		goto fail;
946 	}
947 	wpa_hexdump(MSG_MSGDUMP, "DPP: PrivateKeyAlgorithmIdentifier params",
948 		    params, params_len);
949 	/*
950 	 * ECParameters ::= CHOICE {
951 	 *    namedCurve	OBJECT IDENTIFIER
952 	 *    -- implicitCurve	NULL
953 	 *    -- specifiedCurve	SpecifiedECDomain}
954 	 */
955 	if (!params || asn1_get_oid(params, params_len, &oid, &next) < 0) {
956 		wpa_printf(MSG_DEBUG,
957 			   "DPP: Could not parse ECParameters.namedCurve");
958 		goto fail;
959 	}
960 	asn1_oid_to_str(&oid, txt, sizeof(txt));
961 	wpa_printf(MSG_MSGDUMP, "DPP: namedCurve %s", txt);
962 	/* Assume the curve is identified within ECPrivateKey, so that this
963 	 * separate indication is not really needed. */
964 
965 	/*
966 	 * PrivateKey ::= OCTET STRING
967 	 *    (Contains DER encoding of ECPrivateKey)
968 	 */
969 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
970 	    !asn1_is_octetstring(&hdr)) {
971 		asn1_unexpected(&hdr,
972 				"DPP: Expected OCTETSTRING (PrivateKey)");
973 		goto fail;
974 	}
975 	wpa_hexdump_key(MSG_MSGDUMP, "DPP: PrivateKey",
976 			hdr.payload, hdr.length);
977 	pos = hdr.payload + hdr.length;
978 	eckey = d2i_ECPrivateKey(NULL, &hdr.payload, hdr.length);
979 	if (!eckey) {
980 		wpa_printf(MSG_INFO,
981 			   "DPP: OpenSSL: d2i_ECPrivateKey() failed: %s",
982 			   ERR_error_string(ERR_get_error(), NULL));
983 		goto fail;
984 	}
985 	key->csign = EVP_PKEY_new();
986 	if (!key->csign || EVP_PKEY_assign_EC_KEY(key->csign, eckey) != 1) {
987 		EC_KEY_free(eckey);
988 		goto fail;
989 	}
990 	if (wpa_debug_show_keys)
991 		dpp_debug_print_key("DPP: Received c-sign-key", key->csign);
992 
993 	/*
994 	 * Attributes ::= SET OF Attribute { { OneAsymmetricKeyAttributes } }
995 	 *
996 	 * Exactly one instance of type Attribute in OneAsymmetricKey.
997 	 */
998 	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
999 	    !asn1_is_cs_tag(&hdr, 0)) {
1000 		asn1_unexpected(&hdr, "DPP: Expected [0] Attributes");
1001 		goto fail;
1002 	}
1003 	wpa_hexdump_key(MSG_MSGDUMP, "DPP: Attributes",
1004 			hdr.payload, hdr.length);
1005 	if (hdr.payload + hdr.length < end) {
1006 		wpa_hexdump_key(MSG_MSGDUMP,
1007 				"DPP: Ignore additional data at the end of OneAsymmetricKey",
1008 				hdr.payload + hdr.length,
1009 				end - (hdr.payload + hdr.length));
1010 	}
1011 	pos = hdr.payload;
1012 	end = hdr.payload + hdr.length;
1013 
1014 	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !asn1_is_set(&hdr)) {
1015 		asn1_unexpected(&hdr, "DPP: Expected SET (Attributes)");
1016 		goto fail;
1017 	}
1018 	if (hdr.payload + hdr.length < end) {
1019 		wpa_hexdump_key(MSG_MSGDUMP,
1020 				"DPP: Ignore additional data at the end of OneAsymmetricKey (after SET)",
1021 				hdr.payload + hdr.length,
1022 				end - (hdr.payload + hdr.length));
1023 	}
1024 	pos = hdr.payload;
1025 	end = hdr.payload + hdr.length;
1026 
1027 	/*
1028 	 * OneAsymmetricKeyAttributes ATTRIBUTE ::= {
1029 	 *    aa-DPPConfigurationParameters,
1030 	 *    ... -- For local profiles
1031 	 * }
1032 	 *
1033 	 * aa-DPPConfigurationParameters ATTRIBUTE ::=
1034 	 * { TYPE DPPConfigurationParameters IDENTIFIED BY id-DPPConfigParams }
1035 	 *
1036 	 * Attribute ::= SEQUENCE {
1037 	 *    type OBJECT IDENTIFIER,
1038 	 *    values SET SIZE(1..MAX) OF Type
1039 	 *
1040 	 * Exactly one instance of ATTRIBUTE in attrValues.
1041 	 */
1042 	if (asn1_get_sequence(pos, end - pos, &hdr, &pos) < 0)
1043 		goto fail;
1044 	if (pos < end) {
1045 		wpa_hexdump_key(MSG_MSGDUMP,
1046 				"DPP: Ignore additional data at the end of ATTRIBUTE",
1047 				pos, end - pos);
1048 	}
1049 	end = pos;
1050 	pos = hdr.payload;
1051 
1052 	if (asn1_get_oid(pos, end - pos, &oid, &pos) < 0)
1053 		goto fail;
1054 	if (!asn1_oid_equal(&oid, &asn1_dpp_config_params_oid)) {
1055 		asn1_oid_to_str(&oid, txt, sizeof(txt));
1056 		wpa_printf(MSG_DEBUG,
1057 			   "DPP: Unexpected Attribute identifier %s", txt);
1058 		goto fail;
1059 	}
1060 
1061 	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !asn1_is_set(&hdr)) {
1062 		asn1_unexpected(&hdr, "DPP: Expected SET (Attribute)");
1063 		goto fail;
1064 	}
1065 	pos = hdr.payload;
1066 	end = hdr.payload + hdr.length;
1067 
1068 	/*
1069 	 * DPPConfigurationParameters ::= SEQUENCE {
1070 	 *    privacyProtectionKey      PrivateKey,
1071 	 *    configurationTemplate	UTF8String,
1072 	 *    connectorTemplate		UTF8String OPTIONAL}
1073 	 */
1074 
1075 	wpa_hexdump_key(MSG_MSGDUMP, "DPP: DPPConfigurationParameters",
1076 			pos, end - pos);
1077 	if (asn1_get_sequence(pos, end - pos, &hdr, &pos) < 0)
1078 		goto fail;
1079 	if (pos < end) {
1080 		wpa_hexdump_key(MSG_MSGDUMP,
1081 				"DPP: Ignore additional data after DPPConfigurationParameters",
1082 				pos, end - pos);
1083 	}
1084 	end = pos;
1085 	pos = hdr.payload;
1086 
1087 	/*
1088 	 * PrivateKey ::= OCTET STRING
1089 	 *    (Contains DER encoding of ECPrivateKey)
1090 	 */
1091 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1092 	    !asn1_is_octetstring(&hdr)) {
1093 		asn1_unexpected(&hdr, "DPP: Expected OCTETSTRING (PrivateKey)");
1094 		goto fail;
1095 	}
1096 	wpa_hexdump_key(MSG_MSGDUMP, "DPP: privacyProtectionKey",
1097 			hdr.payload, hdr.length);
1098 	pos = hdr.payload + hdr.length;
1099 	eckey = d2i_ECPrivateKey(NULL, &hdr.payload, hdr.length);
1100 	if (!eckey) {
1101 		wpa_printf(MSG_INFO,
1102 			   "DPP: OpenSSL: d2i_ECPrivateKey() failed: %s",
1103 			   ERR_error_string(ERR_get_error(), NULL));
1104 		goto fail;
1105 	}
1106 	key->pp_key = EVP_PKEY_new();
1107 	if (!key->pp_key || EVP_PKEY_assign_EC_KEY(key->pp_key, eckey) != 1) {
1108 		EC_KEY_free(eckey);
1109 		goto fail;
1110 	}
1111 	if (wpa_debug_show_keys)
1112 		dpp_debug_print_key("DPP: Received privacyProtectionKey",
1113 				    key->pp_key);
1114 
1115 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1116 	    !asn1_is_utf8string(&hdr)) {
1117 		asn1_unexpected(&hdr,
1118 				"DPP: Expected UTF8STRING (configurationTemplate)");
1119 		goto fail;
1120 	}
1121 	wpa_hexdump_ascii_key(MSG_MSGDUMP, "DPP: configurationTemplate",
1122 			      hdr.payload, hdr.length);
1123 	key->config_template = os_zalloc(hdr.length + 1);
1124 	if (!key->config_template)
1125 		goto fail;
1126 	os_memcpy(key->config_template, hdr.payload, hdr.length);
1127 
1128 	pos = hdr.payload + hdr.length;
1129 
1130 	if (pos < end) {
1131 		if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1132 		    !asn1_is_utf8string(&hdr)) {
1133 			asn1_unexpected(&hdr,
1134 					"DPP: Expected UTF8STRING (connectorTemplate)");
1135 			goto fail;
1136 		}
1137 		wpa_hexdump_ascii_key(MSG_MSGDUMP, "DPP: connectorTemplate",
1138 				      hdr.payload, hdr.length);
1139 		key->connector_template = os_zalloc(hdr.length + 1);
1140 		if (!key->connector_template)
1141 			goto fail;
1142 		os_memcpy(key->connector_template, hdr.payload, hdr.length);
1143 	}
1144 
1145 	return key;
1146 fail:
1147 	wpa_printf(MSG_DEBUG, "DPP: Failed to parse OneAsymmetricKey");
1148 	dpp_free_asymmetric_key(key);
1149 	return NULL;
1150 }
1151 
1152 
1153 static struct dpp_asymmetric_key *
1154 dpp_parse_dpp_asymmetric_key_package(const u8 *key_pkg, size_t key_pkg_len)
1155 {
1156 	struct asn1_hdr hdr;
1157 	const u8 *pos = key_pkg, *end = key_pkg + key_pkg_len;
1158 	struct dpp_asymmetric_key *first = NULL, *last = NULL, *key;
1159 
1160 	wpa_hexdump_key(MSG_MSGDUMP, "DPP: DPPAsymmetricKeyPackage",
1161 			key_pkg, key_pkg_len);
1162 
1163 	/*
1164 	 * DPPAsymmetricKeyPackage ::= AsymmetricKeyPackage
1165 	 *
1166 	 * AsymmetricKeyPackage ::= SEQUENCE SIZE (1..MAX) OF OneAsymmetricKey
1167 	 */
1168 	while (pos < end) {
1169 		if (asn1_get_sequence(pos, end - pos, &hdr, &pos) < 0 ||
1170 		    !(key = dpp_parse_one_asymmetric_key(hdr.payload,
1171 							 hdr.length))) {
1172 			dpp_free_asymmetric_key(first);
1173 			return NULL;
1174 		}
1175 		if (!last) {
1176 			first = last = key;
1177 		} else {
1178 			last->next = key;
1179 			last = key;
1180 		}
1181 	}
1182 
1183 	return first;
1184 }
1185 
1186 
1187 int dpp_conf_resp_env_data(struct dpp_authentication *auth,
1188 			   const u8 *env_data, size_t env_data_len)
1189 {
1190 	u8 key[DPP_MAX_HASH_LEN];
1191 	size_t key_len;
1192 	u8 kek[DPP_MAX_HASH_LEN];
1193 	u8 cont_encr_key[DPP_MAX_HASH_LEN];
1194 	size_t cont_encr_key_len;
1195 	int res;
1196 	u8 *key_pkg;
1197 	size_t key_pkg_len;
1198 	struct dpp_enveloped_data data;
1199 	struct dpp_asymmetric_key *keys;
1200 
1201 	wpa_hexdump(MSG_DEBUG, "DPP: DPPEnvelopedData", env_data, env_data_len);
1202 
1203 	if (dpp_parse_enveloped_data(env_data, env_data_len, &data) < 0)
1204 		return -1;
1205 
1206 	key_len = auth->curve->hash_len;
1207 	/* password = HKDF-Expand(bk, "Enveloped Data Password", length) */
1208 	res = dpp_hkdf_expand(key_len, auth->bk, key_len,
1209 			      "Enveloped Data Password", key, key_len);
1210 	if (res < 0)
1211 		return -1;
1212 	wpa_hexdump_key(MSG_DEBUG, "DPP: PBKDF2 key", key, key_len);
1213 
1214 	if (dpp_pbkdf2(data.prf_hash_len, key, key_len, data.salt, 64, 1000,
1215 		       kek, data.pbkdf2_key_len)) {
1216 		wpa_printf(MSG_DEBUG, "DPP: PBKDF2 failed");
1217 		return -1;
1218 	}
1219 	wpa_hexdump_key(MSG_DEBUG, "DPP: key-encryption key from PBKDF2",
1220 			kek, data.pbkdf2_key_len);
1221 
1222 	if (data.enc_key_len < AES_BLOCK_SIZE ||
1223 	    data.enc_key_len > sizeof(cont_encr_key) + AES_BLOCK_SIZE) {
1224 		wpa_printf(MSG_DEBUG, "DPP: Invalid encryptedKey length");
1225 		return -1;
1226 	}
1227 	res = aes_siv_decrypt(kek, data.pbkdf2_key_len,
1228 			      data.enc_key, data.enc_key_len,
1229 			      0, NULL, NULL, cont_encr_key);
1230 	forced_memzero(kek, data.pbkdf2_key_len);
1231 	if (res < 0) {
1232 		wpa_printf(MSG_DEBUG,
1233 			   "DPP: AES-SIV decryption of encryptedKey failed");
1234 		return -1;
1235 	}
1236 	cont_encr_key_len = data.enc_key_len - AES_BLOCK_SIZE;
1237 	wpa_hexdump_key(MSG_DEBUG, "DPP: content-encryption key",
1238 			cont_encr_key, cont_encr_key_len);
1239 
1240 	if (data.enc_cont_len < AES_BLOCK_SIZE)
1241 		return -1;
1242 	key_pkg_len = data.enc_cont_len - AES_BLOCK_SIZE;
1243 	key_pkg = os_malloc(key_pkg_len);
1244 	if (!key_pkg)
1245 		return -1;
1246 	res = aes_siv_decrypt(cont_encr_key, cont_encr_key_len,
1247 			      data.enc_cont, data.enc_cont_len,
1248 			      0, NULL, NULL, key_pkg);
1249 	forced_memzero(cont_encr_key, cont_encr_key_len);
1250 	if (res < 0) {
1251 		bin_clear_free(key_pkg, key_pkg_len);
1252 		wpa_printf(MSG_DEBUG,
1253 			   "DPP: AES-SIV decryption of encryptedContent failed");
1254 		return -1;
1255 	}
1256 
1257 	keys = dpp_parse_dpp_asymmetric_key_package(key_pkg, key_pkg_len);
1258 	bin_clear_free(key_pkg, key_pkg_len);
1259 	dpp_free_asymmetric_key(auth->conf_key_pkg);
1260 	auth->conf_key_pkg = keys;
1261 
1262 	return keys != NULL;
1263 }
1264 
1265 #endif /* CONFIG_DPP2 */
1266