• 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 		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 
dpp_build_conf_params(struct dpp_configurator * conf)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 
dpp_build_attribute(struct dpp_configurator * conf)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 
dpp_build_key_alg(const struct dpp_curve_params * curve)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 
dpp_build_key_pkg(struct dpp_authentication * auth)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 
dpp_build_pbkdf2_alg_id(const struct wpabuf * salt,size_t hash_len)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 *
dpp_build_pw_recipient_info(struct dpp_authentication * auth,size_t hash_len,const struct wpabuf * cont_enc_key)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 *
dpp_build_recipient_info(struct dpp_authentication * auth,size_t hash_len,const struct wpabuf * cont_enc_key)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 *
dpp_build_enc_cont_info(struct dpp_authentication * auth,size_t hash_len,const struct wpabuf * cont_enc_key)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 
dpp_gen_random(size_t len)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 
dpp_build_enveloped_data(struct dpp_authentication * auth)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 
dpp_parse_recipient_infos(const u8 * pos,size_t len,struct dpp_enveloped_data * data)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 ||
596 	    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC || hdr.tag != 3) {
597 		wpa_printf(MSG_DEBUG,
598 			   "DPP: Expected CHOICE [3] (pwri) - found class %d tag 0x%x",
599 			   hdr.class, hdr.tag);
600 		return -1;
601 	}
602 	wpa_hexdump(MSG_MSGDUMP, "DPP: PasswordRecipientInfo",
603 		    hdr.payload, hdr.length);
604 	pos = hdr.payload;
605 	end = pos + hdr.length;
606 
607 	/*
608 	 * PasswordRecipientInfo ::= SEQUENCE {
609 	 *    version			CMSVersion,
610 	 *    keyDerivationAlgorithm [0] KeyDerivationAlgorithmIdentifier OPTIONAL,
611 	 *    keyEncryptionAlgorithm	KeyEncryptionAlgorithmIdentifier,
612 	 *    encryptedKey		EncryptedKey}
613 	 *
614 	 * version is 0, keyDerivationAlgorithm is id-PKBDF2, and the
615 	 * parameters contains PBKDF2-params SEQUENCE.
616 	 */
617 
618 	if (asn1_get_sequence(pos, end - pos, &hdr, &end) < 0)
619 		return -1;
620 	pos = hdr.payload;
621 
622 	if (asn1_get_integer(pos, end - pos, &val, &pos) < 0)
623 		return -1;
624 	if (val != 0) {
625 		wpa_printf(MSG_DEBUG, "DPP: pwri.version != 0");
626 		return -1;
627 	}
628 
629 	wpa_hexdump(MSG_MSGDUMP, "DPP: Remaining PasswordRecipientInfo after version",
630 		    pos, end - pos);
631 
632 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
633 	    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC || hdr.tag != 0) {
634 		wpa_printf(MSG_DEBUG,
635 			   "DPP: Expected keyDerivationAlgorithm [0] - found class %d tag 0x%x",
636 			   hdr.class, hdr.tag);
637 		return -1;
638 	}
639 	pos = hdr.payload;
640 	e_end = pos + hdr.length;
641 
642 	/* KeyDerivationAlgorithmIdentifier ::= AlgorithmIdentifier */
643 	if (asn1_get_alg_id(pos, e_end - pos, &oid, &params, &params_len,
644 			    &next) < 0)
645 		return -1;
646 	if (!asn1_oid_equal(&oid, &asn1_pbkdf2_oid)) {
647 		char buf[80];
648 
649 		asn1_oid_to_str(&oid, buf, sizeof(buf));
650 		wpa_printf(MSG_DEBUG,
651 			   "DPP: Unexpected KeyDerivationAlgorithmIdentifier %s",
652 			   buf);
653 		return -1;
654 	}
655 
656 	/*
657 	 * PBKDF2-params ::= SEQUENCE {
658 	 *    salt CHOICE {
659 	 *       specified OCTET STRING,
660 	 *       otherSource AlgorithmIdentifier}
661 	 *    iterationCount INTEGER (1..MAX),
662 	 *    keyLength INTEGER (1..MAX),
663 	 *    prf AlgorithmIdentifier}
664 	 *
665 	 * salt is an 64 octet value, iterationCount is 1000, keyLength is based
666 	 * on Configurator signing key length, prf is
667 	 * id-hmacWithSHA{256,384,512} based on Configurator signing key.
668 	 */
669 	if (!params ||
670 	    asn1_get_sequence(params, params_len, &hdr, &e_end) < 0)
671 		return -1;
672 	pos = hdr.payload;
673 
674 	if (asn1_get_next(pos, e_end - pos, &hdr) < 0 ||
675 	    hdr.class != ASN1_CLASS_UNIVERSAL ||
676 	    hdr.tag != ASN1_TAG_OCTETSTRING) {
677 		wpa_printf(MSG_DEBUG,
678 			   "DPP: Expected OCTETSTRING (salt.specified) - found class %d tag 0x%x",
679 			   hdr.class, hdr.tag);
680 		return -1;
681 	}
682 	wpa_hexdump(MSG_MSGDUMP, "DPP: salt.specified",
683 		    hdr.payload, hdr.length);
684 	if (hdr.length != 64) {
685 		wpa_printf(MSG_DEBUG, "DPP: Unexpected salt length %u",
686 			   hdr.length);
687 		return -1;
688 	}
689 	data->salt = hdr.payload;
690 	pos = hdr.payload + hdr.length;
691 
692 	if (asn1_get_integer(pos, e_end - pos, &val, &pos) < 0)
693 		return -1;
694 	if (val != 1000) {
695 		wpa_printf(MSG_DEBUG, "DPP: Unexpected iterationCount %d", val);
696 		return -1;
697 	}
698 
699 	if (asn1_get_integer(pos, e_end - pos, &val, &pos) < 0)
700 		return -1;
701 	if (val != 32 && val != 48 && val != 64) {
702 		wpa_printf(MSG_DEBUG, "DPP: Unexpected keyLength %d", val);
703 		return -1;
704 	}
705 	data->pbkdf2_key_len = val;
706 
707 	if (asn1_get_sequence(pos, e_end - pos, &hdr, NULL) < 0 ||
708 	    asn1_get_oid(hdr.payload, hdr.length, &oid, &pos) < 0) {
709 		wpa_printf(MSG_DEBUG, "DPP: Could not parse prf");
710 		return -1;
711 	}
712 	if (asn1_oid_equal(&oid, &asn1_pbkdf2_hmac_sha256_oid)) {
713 		data->prf_hash_len = 32;
714 	} else if (asn1_oid_equal(&oid, &asn1_pbkdf2_hmac_sha384_oid)) {
715 		data->prf_hash_len = 48;
716 	} else if (asn1_oid_equal(&oid, &asn1_pbkdf2_hmac_sha512_oid)) {
717 		data->prf_hash_len = 64;
718 	} else {
719 		char buf[80];
720 
721 		asn1_oid_to_str(&oid, buf, sizeof(buf));
722 		wpa_printf(MSG_DEBUG, "DPP: Unexpected PBKDF2-params.prf %s",
723 			   buf);
724 		return -1;
725 	}
726 
727 	pos = next;
728 
729 	/* keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier
730 	 *
731 	 * KeyEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
732 	 *
733 	 * id-alg-AES-SIV-CMAC-aed-256, id-alg-AES-SIV-CMAC-aed-384, or
734 	 * id-alg-AES-SIV-CMAC-aed-512. */
735 	if (asn1_get_alg_id(pos, end - pos, &oid, NULL, NULL, &pos) < 0)
736 		return -1;
737 	if (!asn1_oid_equal(&oid, &asn1_aes_siv_cmac_aead_256_oid) &&
738 	    !asn1_oid_equal(&oid, &asn1_aes_siv_cmac_aead_384_oid) &&
739 	    !asn1_oid_equal(&oid, &asn1_aes_siv_cmac_aead_512_oid)) {
740 		char buf[80];
741 
742 		asn1_oid_to_str(&oid, buf, sizeof(buf));
743 		wpa_printf(MSG_DEBUG,
744 			   "DPP: Unexpected KeyEncryptionAlgorithmIdentifier %s",
745 			   buf);
746 		return -1;
747 	}
748 
749 	/*
750 	 * encryptedKey EncryptedKey
751 	 *
752 	 * EncryptedKey ::= OCTET STRING
753 	 */
754 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
755 	    hdr.class != ASN1_CLASS_UNIVERSAL ||
756 	    hdr.tag != ASN1_TAG_OCTETSTRING) {
757 		wpa_printf(MSG_DEBUG,
758 			   "DPP: Expected OCTETSTRING (pwri.encryptedKey) - found class %d tag 0x%x",
759 			   hdr.class, hdr.tag);
760 		return -1;
761 	}
762 	wpa_hexdump(MSG_MSGDUMP, "DPP: pwri.encryptedKey",
763 		    hdr.payload, hdr.length);
764 	data->enc_key = hdr.payload;
765 	data->enc_key_len = hdr.length;
766 
767 	return 0;
768 }
769 
770 
dpp_parse_encrypted_content_info(const u8 * pos,const u8 * end,struct dpp_enveloped_data * data)771 static int dpp_parse_encrypted_content_info(const u8 *pos, const u8 *end,
772 					    struct dpp_enveloped_data *data)
773 {
774 	struct asn1_hdr hdr;
775 	struct asn1_oid oid;
776 
777 	/*
778 	 * EncryptedContentInfo ::= SEQUENCE {
779 	 *    contentType			ContentType,
780 	 *    contentEncryptionAlgorithm  ContentEncryptionAlgorithmIdentifier,
781 	 *    encryptedContent	[0] IMPLICIT	EncryptedContent OPTIONAL}
782 	 */
783 	if (asn1_get_sequence(pos, end - pos, &hdr, &pos) < 0)
784 		return -1;
785 	wpa_hexdump(MSG_MSGDUMP, "DPP: EncryptedContentInfo",
786 		    hdr.payload, hdr.length);
787 	if (pos < end) {
788 		wpa_hexdump(MSG_DEBUG,
789 			    "DPP: Unexpected extra data after EncryptedContentInfo",
790 			    pos, end - pos);
791 		return -1;
792 	}
793 
794 	end = pos;
795 	pos = hdr.payload;
796 
797 	/* ContentType ::= OBJECT IDENTIFIER */
798 	if (asn1_get_oid(pos, end - pos, &oid, &pos) < 0) {
799 		wpa_printf(MSG_DEBUG, "DPP: Could not parse ContentType");
800 		return -1;
801 	}
802 	if (!asn1_oid_equal(&oid, &asn1_dpp_asymmetric_key_package_oid)) {
803 		char buf[80];
804 
805 		asn1_oid_to_str(&oid, buf, sizeof(buf));
806 		wpa_printf(MSG_DEBUG, "DPP: Unexpected ContentType %s", buf);
807 		return -1;
808 	}
809 
810 	/* ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier */
811 	if (asn1_get_alg_id(pos, end - pos, &oid, NULL, NULL, &pos) < 0)
812 		return -1;
813 	if (!asn1_oid_equal(&oid, &asn1_aes_siv_cmac_aead_256_oid) &&
814 	    !asn1_oid_equal(&oid, &asn1_aes_siv_cmac_aead_384_oid) &&
815 	    !asn1_oid_equal(&oid, &asn1_aes_siv_cmac_aead_512_oid)) {
816 		char buf[80];
817 
818 		asn1_oid_to_str(&oid, buf, sizeof(buf));
819 		wpa_printf(MSG_DEBUG,
820 			   "DPP: Unexpected ContentEncryptionAlgorithmIdentifier %s",
821 			   buf);
822 		return -1;
823 	}
824 	/* ignore optional parameters */
825 
826 	/* encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL
827 	 * EncryptedContent ::= OCTET STRING */
828 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
829 	    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC || hdr.tag != 0) {
830 		wpa_printf(MSG_DEBUG,
831 			   "DPP: Expected [0] IMPLICIT (EncryptedContent) - found class %d tag 0x%x",
832 			   hdr.class, hdr.tag);
833 		return -1;
834 	}
835 	wpa_hexdump(MSG_MSGDUMP, "DPP: EncryptedContent",
836 		    hdr.payload, hdr.length);
837 	data->enc_cont = hdr.payload;
838 	data->enc_cont_len = hdr.length;
839 	return 0;
840 }
841 
842 
dpp_parse_enveloped_data(const u8 * env_data,size_t env_data_len,struct dpp_enveloped_data * data)843 static int dpp_parse_enveloped_data(const u8 *env_data, size_t env_data_len,
844 				    struct dpp_enveloped_data *data)
845 {
846 	struct asn1_hdr hdr;
847 	const u8 *pos, *end;
848 	int val;
849 
850 	os_memset(data, 0, sizeof(*data));
851 
852 	/*
853 	 * DPPEnvelopedData ::= EnvelopedData
854 	 *
855 	 * EnvelopedData ::= SEQUENCE {
856 	 *    version			CMSVersion,
857 	 *    originatorInfo	[0]	IMPLICIT OriginatorInfo OPTIONAL,
858 	 *    recipientInfos		RecipientInfos,
859 	 *    encryptedContentInfo	EncryptedContentInfo,
860 	 *    unprotectedAttrs  [1] IMPLICIT	UnprotectedAttributes OPTIONAL}
861 	 *
862 	 * CMSVersion ::= INTEGER
863 	 *
864 	 * RecipientInfos ::= SET SIZE (1..MAX) OF RecipientInfo
865 	 *
866 	 * For DPP, version is 3, both originatorInfo and
867 	 * unprotectedAttrs are omitted, and recipientInfos contains a single
868 	 * RecipientInfo.
869 	 */
870 	if (asn1_get_sequence(env_data, env_data_len, &hdr, &end) < 0)
871 		return -1;
872 	pos = hdr.payload;
873 	if (end < env_data + env_data_len) {
874 		wpa_hexdump(MSG_DEBUG,
875 			    "DPP: Unexpected extra data after DPPEnvelopedData",
876 			    end, env_data + env_data_len - end);
877 		return -1;
878 	}
879 
880 	if (asn1_get_integer(pos, end - pos, &val, &pos) < 0)
881 		return -1;
882 	if (val != 3) {
883 		wpa_printf(MSG_DEBUG, "DPP: EnvelopedData.version != 3");
884 		return -1;
885 	}
886 
887 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
888 	    hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_SET) {
889 		wpa_printf(MSG_DEBUG,
890 			   "DPP: Expected SET (RecipientInfos) - found class %d tag 0x%x",
891 			   hdr.class, hdr.tag);
892 		return -1;
893 	}
894 
895 	if (dpp_parse_recipient_infos(hdr.payload, hdr.length, data) < 0)
896 		return -1;
897 	return dpp_parse_encrypted_content_info(hdr.payload + hdr.length, end,
898 						data);
899 }
900 
901 
902 static struct dpp_asymmetric_key *
dpp_parse_one_asymmetric_key(const u8 * buf,size_t len)903 dpp_parse_one_asymmetric_key(const u8 *buf, size_t len)
904 {
905 	struct asn1_hdr hdr;
906 	const u8 *pos = buf, *end = buf + len, *next;
907 	int val;
908 	const u8 *params;
909 	size_t params_len;
910 	struct asn1_oid oid;
911 	char txt[80];
912 	struct dpp_asymmetric_key *key;
913 	EC_KEY *eckey;
914 
915 	wpa_hexdump_key(MSG_MSGDUMP, "DPP: OneAsymmetricKey", buf, len);
916 
917 	key = os_zalloc(sizeof(*key));
918 	if (!key)
919 		return NULL;
920 
921 	/*
922 	 * OneAsymmetricKey ::= SEQUENCE {
923 	 *    version			Version,
924 	 *    privateKeyAlgorithm	PrivateKeyAlgorithmIdentifier,
925 	 *    privateKey		PrivateKey,
926 	 *    attributes		[0] Attributes OPTIONAL,
927 	 *    ...,
928 	 *    [[2: publicKey		[1] BIT STRING OPTIONAL ]],
929 	 *    ...
930 	 * }
931 	 */
932 	if (asn1_get_sequence(pos, end - pos, &hdr, &end) < 0)
933 		goto fail;
934 	pos = hdr.payload;
935 
936 	/* Version ::= INTEGER { v1(0), v2(1) } (v1, ..., v2) */
937 	if (asn1_get_integer(pos, end - pos, &val, &pos) < 0)
938 		goto fail;
939 	if (val != 0 && val != 1) {
940 		wpa_printf(MSG_DEBUG,
941 			   "DPP: Unsupported DPPAsymmetricKeyPackage version %d",
942 			   val);
943 		goto fail;
944 	}
945 
946 	/* PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier */
947 	if (asn1_get_alg_id(pos, end - pos, &oid, &params, &params_len,
948 			    &pos) < 0)
949 		goto fail;
950 	if (!asn1_oid_equal(&oid, &asn1_ec_public_key_oid)) {
951 		asn1_oid_to_str(&oid, txt, sizeof(txt));
952 		wpa_printf(MSG_DEBUG,
953 			   "DPP: Unsupported PrivateKeyAlgorithmIdentifier %s",
954 			   txt);
955 		goto fail;
956 	}
957 	wpa_hexdump(MSG_MSGDUMP, "DPP: PrivateKeyAlgorithmIdentifier params",
958 		    params, params_len);
959 	/*
960 	 * ECParameters ::= CHOICE {
961 	 *    namedCurve	OBJECT IDENTIFIER
962 	 *    -- implicitCurve	NULL
963 	 *    -- specifiedCurve	SpecifiedECDomain}
964 	 */
965 	if (!params || asn1_get_oid(params, params_len, &oid, &next) < 0) {
966 		wpa_printf(MSG_DEBUG,
967 			   "DPP: Could not parse ECParameters.namedCurve");
968 		goto fail;
969 	}
970 	asn1_oid_to_str(&oid, txt, sizeof(txt));
971 	wpa_printf(MSG_MSGDUMP, "DPP: namedCurve %s", txt);
972 	/* Assume the curve is identified within ECPrivateKey, so that this
973 	 * separate indication is not really needed. */
974 
975 	/*
976 	 * PrivateKey ::= OCTET STRING
977 	 *    (Contains DER encoding of ECPrivateKey)
978 	 */
979 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
980 	    hdr.class != ASN1_CLASS_UNIVERSAL ||
981 	    hdr.tag != ASN1_TAG_OCTETSTRING) {
982 		wpa_printf(MSG_DEBUG,
983 			   "DPP: Expected OCTETSTRING (PrivateKey) - found class %d tag 0x%x",
984 			   hdr.class, hdr.tag);
985 		goto fail;
986 	}
987 	wpa_hexdump_key(MSG_MSGDUMP, "DPP: PrivateKey",
988 			hdr.payload, hdr.length);
989 	pos = hdr.payload + hdr.length;
990 	eckey = d2i_ECPrivateKey(NULL, &hdr.payload, hdr.length);
991 	if (!eckey) {
992 		wpa_printf(MSG_INFO,
993 			   "DPP: OpenSSL: d2i_ECPrivateKey() failed: %s",
994 			   ERR_error_string(ERR_get_error(), NULL));
995 		goto fail;
996 	}
997 	key->csign = EVP_PKEY_new();
998 	if (!key->csign || EVP_PKEY_assign_EC_KEY(key->csign, eckey) != 1) {
999 		EC_KEY_free(eckey);
1000 		goto fail;
1001 	}
1002 	if (wpa_debug_show_keys)
1003 		dpp_debug_print_key("DPP: Received c-sign-key", key->csign);
1004 
1005 	/*
1006 	 * Attributes ::= SET OF Attribute { { OneAsymmetricKeyAttributes } }
1007 	 *
1008 	 * Exactly one instance of type Attribute in OneAsymmetricKey.
1009 	 */
1010 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1011 	    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC || hdr.tag != 0) {
1012 		wpa_printf(MSG_DEBUG,
1013 			   "DPP: Expected [0] Attributes - found class %d tag 0x%x",
1014 			   hdr.class, hdr.tag);
1015 		goto fail;
1016 	}
1017 	wpa_hexdump_key(MSG_MSGDUMP, "DPP: Attributes",
1018 			hdr.payload, hdr.length);
1019 	if (hdr.payload + hdr.length < end) {
1020 		wpa_hexdump_key(MSG_MSGDUMP,
1021 				"DPP: Ignore additional data at the end of OneAsymmetricKey",
1022 				hdr.payload + hdr.length,
1023 				end - (hdr.payload + hdr.length));
1024 	}
1025 	pos = hdr.payload;
1026 	end = hdr.payload + hdr.length;
1027 
1028 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1029 	    hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_SET) {
1030 		wpa_printf(MSG_DEBUG,
1031 			   "DPP: Expected SET (Attributes) - found class %d tag 0x%x",
1032 			   hdr.class, hdr.tag);
1033 		goto fail;
1034 	}
1035 	if (hdr.payload + hdr.length < end) {
1036 		wpa_hexdump_key(MSG_MSGDUMP,
1037 				"DPP: Ignore additional data at the end of OneAsymmetricKey (after SET)",
1038 				hdr.payload + hdr.length,
1039 				end - (hdr.payload + hdr.length));
1040 	}
1041 	pos = hdr.payload;
1042 	end = hdr.payload + hdr.length;
1043 
1044 	/*
1045 	 * OneAsymmetricKeyAttributes ATTRIBUTE ::= {
1046 	 *    aa-DPPConfigurationParameters,
1047 	 *    ... -- For local profiles
1048 	 * }
1049 	 *
1050 	 * aa-DPPConfigurationParameters ATTRIBUTE ::=
1051 	 * { TYPE DPPConfigurationParameters IDENTIFIED BY id-DPPConfigParams }
1052 	 *
1053 	 * Attribute ::= SEQUENCE {
1054 	 *    type OBJECT IDENTIFIER,
1055 	 *    values SET SIZE(1..MAX) OF Type
1056 	 *
1057 	 * Exactly one instance of ATTRIBUTE in attrValues.
1058 	 */
1059 	if (asn1_get_sequence(pos, end - pos, &hdr, &pos) < 0)
1060 		goto fail;
1061 	if (pos < end) {
1062 		wpa_hexdump_key(MSG_MSGDUMP,
1063 				"DPP: Ignore additional data at the end of ATTRIBUTE",
1064 				pos, end - pos);
1065 	}
1066 	end = pos;
1067 	pos = hdr.payload;
1068 
1069 	if (asn1_get_oid(pos, end - pos, &oid, &pos) < 0)
1070 		goto fail;
1071 	if (!asn1_oid_equal(&oid, &asn1_dpp_config_params_oid)) {
1072 		asn1_oid_to_str(&oid, txt, sizeof(txt));
1073 		wpa_printf(MSG_DEBUG,
1074 			   "DPP: Unexpected Attribute identifier %s", txt);
1075 		goto fail;
1076 	}
1077 
1078 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1079 	    hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_SET) {
1080 		wpa_printf(MSG_DEBUG,
1081 			   "DPP: Expected SET (Attribute) - found class %d tag 0x%x",
1082 			   hdr.class, hdr.tag);
1083 		goto fail;
1084 	}
1085 	pos = hdr.payload;
1086 	end = hdr.payload + hdr.length;
1087 
1088 	/*
1089 	 * DPPConfigurationParameters ::= SEQUENCE {
1090 	 *    privacyProtectionKey      PrivateKey,
1091 	 *    configurationTemplate	UTF8String,
1092 	 *    connectorTemplate		UTF8String OPTIONAL}
1093 	 */
1094 
1095 	wpa_hexdump_key(MSG_MSGDUMP, "DPP: DPPConfigurationParameters",
1096 			pos, end - pos);
1097 	if (asn1_get_sequence(pos, end - pos, &hdr, &pos) < 0)
1098 		goto fail;
1099 	if (pos < end) {
1100 		wpa_hexdump_key(MSG_MSGDUMP,
1101 				"DPP: Ignore additional data after DPPConfigurationParameters",
1102 				pos, end - pos);
1103 	}
1104 	end = pos;
1105 	pos = hdr.payload;
1106 
1107 	/*
1108 	 * PrivateKey ::= OCTET STRING
1109 	 *    (Contains DER encoding of ECPrivateKey)
1110 	 */
1111 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1112 	    hdr.class != ASN1_CLASS_UNIVERSAL ||
1113 	    hdr.tag != ASN1_TAG_OCTETSTRING) {
1114 		wpa_printf(MSG_DEBUG,
1115 			   "DPP: Expected OCTETSTRING (PrivateKey) - found class %d tag 0x%x",
1116 			   hdr.class, hdr.tag);
1117 		goto fail;
1118 	}
1119 	wpa_hexdump_key(MSG_MSGDUMP, "DPP: privacyProtectionKey",
1120 			hdr.payload, hdr.length);
1121 	pos = hdr.payload + hdr.length;
1122 	eckey = d2i_ECPrivateKey(NULL, &hdr.payload, hdr.length);
1123 	if (!eckey) {
1124 		wpa_printf(MSG_INFO,
1125 			   "DPP: OpenSSL: d2i_ECPrivateKey() failed: %s",
1126 			   ERR_error_string(ERR_get_error(), NULL));
1127 		goto fail;
1128 	}
1129 	key->pp_key = EVP_PKEY_new();
1130 	if (!key->pp_key || EVP_PKEY_assign_EC_KEY(key->pp_key, eckey) != 1) {
1131 		EC_KEY_free(eckey);
1132 		goto fail;
1133 	}
1134 	if (wpa_debug_show_keys)
1135 		dpp_debug_print_key("DPP: Received privacyProtectionKey",
1136 				    key->pp_key);
1137 
1138 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1139 	    hdr.class != ASN1_CLASS_UNIVERSAL ||
1140 	    hdr.tag != ASN1_TAG_UTF8STRING) {
1141 		wpa_printf(MSG_DEBUG,
1142 			   "DPP: Expected UTF8STRING (configurationTemplate) - found class %d tag 0x%x",
1143 			   hdr.class, hdr.tag);
1144 		goto fail;
1145 	}
1146 	wpa_hexdump_ascii_key(MSG_MSGDUMP, "DPP: configurationTemplate",
1147 			      hdr.payload, hdr.length);
1148 	key->config_template = os_zalloc(hdr.length + 1);
1149 	if (!key->config_template)
1150 		goto fail;
1151 	os_memcpy(key->config_template, hdr.payload, hdr.length);
1152 
1153 	pos = hdr.payload + hdr.length;
1154 
1155 	if (pos < end) {
1156 		if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1157 		    hdr.class != ASN1_CLASS_UNIVERSAL ||
1158 		    hdr.tag != ASN1_TAG_UTF8STRING) {
1159 			wpa_printf(MSG_DEBUG,
1160 				   "DPP: Expected UTF8STRING (connectorTemplate) - found class %d tag 0x%x",
1161 				   hdr.class, hdr.tag);
1162 			goto fail;
1163 		}
1164 		wpa_hexdump_ascii_key(MSG_MSGDUMP, "DPP: connectorTemplate",
1165 				      hdr.payload, hdr.length);
1166 		key->connector_template = os_zalloc(hdr.length + 1);
1167 		if (!key->connector_template)
1168 			goto fail;
1169 		os_memcpy(key->connector_template, hdr.payload, hdr.length);
1170 	}
1171 
1172 	return key;
1173 fail:
1174 	wpa_printf(MSG_DEBUG, "DPP: Failed to parse OneAsymmetricKey");
1175 	dpp_free_asymmetric_key(key);
1176 	return NULL;
1177 }
1178 
1179 
1180 static struct dpp_asymmetric_key *
dpp_parse_dpp_asymmetric_key_package(const u8 * key_pkg,size_t key_pkg_len)1181 dpp_parse_dpp_asymmetric_key_package(const u8 *key_pkg, size_t key_pkg_len)
1182 {
1183 	struct asn1_hdr hdr;
1184 	const u8 *pos = key_pkg, *end = key_pkg + key_pkg_len;
1185 	struct dpp_asymmetric_key *first = NULL, *last = NULL, *key;
1186 
1187 	wpa_hexdump_key(MSG_MSGDUMP, "DPP: DPPAsymmetricKeyPackage",
1188 			key_pkg, key_pkg_len);
1189 
1190 	/*
1191 	 * DPPAsymmetricKeyPackage ::= AsymmetricKeyPackage
1192 	 *
1193 	 * AsymmetricKeyPackage ::= SEQUENCE SIZE (1..MAX) OF OneAsymmetricKey
1194 	 */
1195 	while (pos < end) {
1196 		if (asn1_get_sequence(pos, end - pos, &hdr, &pos) < 0 ||
1197 		    !(key = dpp_parse_one_asymmetric_key(hdr.payload,
1198 							 hdr.length))) {
1199 			dpp_free_asymmetric_key(first);
1200 			return NULL;
1201 		}
1202 		if (!last) {
1203 			first = last = key;
1204 		} else {
1205 			last->next = key;
1206 			last = key;
1207 		}
1208 	}
1209 
1210 	return first;
1211 }
1212 
1213 
dpp_conf_resp_env_data(struct dpp_authentication * auth,const u8 * env_data,size_t env_data_len)1214 int dpp_conf_resp_env_data(struct dpp_authentication *auth,
1215 			   const u8 *env_data, size_t env_data_len)
1216 {
1217 	u8 key[DPP_MAX_HASH_LEN];
1218 	size_t key_len;
1219 	u8 kek[DPP_MAX_HASH_LEN];
1220 	u8 cont_encr_key[DPP_MAX_HASH_LEN];
1221 	size_t cont_encr_key_len;
1222 	int res;
1223 	u8 *key_pkg;
1224 	size_t key_pkg_len;
1225 	struct dpp_enveloped_data data;
1226 	struct dpp_asymmetric_key *keys;
1227 
1228 	wpa_hexdump(MSG_DEBUG, "DPP: DPPEnvelopedData", env_data, env_data_len);
1229 
1230 	if (dpp_parse_enveloped_data(env_data, env_data_len, &data) < 0)
1231 		return -1;
1232 
1233 	key_len = auth->curve->hash_len;
1234 	/* password = HKDF-Expand(bk, "Enveloped Data Password", length) */
1235 	res = dpp_hkdf_expand(key_len, auth->bk, key_len,
1236 			      "Enveloped Data Password", key, key_len);
1237 	if (res < 0)
1238 		return -1;
1239 	wpa_hexdump_key(MSG_DEBUG, "DPP: PBKDF2 key", key, key_len);
1240 
1241 	if (dpp_pbkdf2(data.prf_hash_len, key, key_len, data.salt, 64, 1000,
1242 		       kek, data.pbkdf2_key_len)) {
1243 		wpa_printf(MSG_DEBUG, "DPP: PBKDF2 failed");
1244 		return -1;
1245 	}
1246 	wpa_hexdump_key(MSG_DEBUG, "DPP: key-encryption key from PBKDF2",
1247 			kek, data.pbkdf2_key_len);
1248 
1249 	if (data.enc_key_len < AES_BLOCK_SIZE ||
1250 	    data.enc_key_len > sizeof(cont_encr_key) + AES_BLOCK_SIZE) {
1251 		wpa_printf(MSG_DEBUG, "DPP: Invalid encryptedKey length");
1252 		return -1;
1253 	}
1254 	res = aes_siv_decrypt(kek, data.pbkdf2_key_len,
1255 			      data.enc_key, data.enc_key_len,
1256 			      0, NULL, NULL, cont_encr_key);
1257 	forced_memzero(kek, data.pbkdf2_key_len);
1258 	if (res < 0) {
1259 		wpa_printf(MSG_DEBUG,
1260 			   "DPP: AES-SIV decryption of encryptedKey failed");
1261 		return -1;
1262 	}
1263 	cont_encr_key_len = data.enc_key_len - AES_BLOCK_SIZE;
1264 	wpa_hexdump_key(MSG_DEBUG, "DPP: content-encryption key",
1265 			cont_encr_key, cont_encr_key_len);
1266 
1267 	if (data.enc_cont_len < AES_BLOCK_SIZE)
1268 		return -1;
1269 	key_pkg_len = data.enc_cont_len - AES_BLOCK_SIZE;
1270 	key_pkg = os_malloc(key_pkg_len);
1271 	if (!key_pkg)
1272 		return -1;
1273 	res = aes_siv_decrypt(cont_encr_key, cont_encr_key_len,
1274 			      data.enc_cont, data.enc_cont_len,
1275 			      0, NULL, NULL, key_pkg);
1276 	forced_memzero(cont_encr_key, cont_encr_key_len);
1277 	if (res < 0) {
1278 		bin_clear_free(key_pkg, key_pkg_len);
1279 		wpa_printf(MSG_DEBUG,
1280 			   "DPP: AES-SIV decryption of encryptedContent failed");
1281 		return -1;
1282 	}
1283 
1284 	keys = dpp_parse_dpp_asymmetric_key_package(key_pkg, key_pkg_len);
1285 	bin_clear_free(key_pkg, key_pkg_len);
1286 	dpp_free_asymmetric_key(auth->conf_key_pkg);
1287 	auth->conf_key_pkg = keys;
1288 
1289 	return keys != NULL;
1290 }
1291 
1292 #endif /* CONFIG_DPP2 */
1293