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