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