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