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