18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * PKCS #5 (Password-based Encryption)
38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details.
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h"
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h"
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/crypto.h"
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/md5.h"
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "asn1.h"
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "pkcs5.h"
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct pkcs5_params {
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enum pkcs5_alg {
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		PKCS5_ALG_UNKNOWN,
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		PKCS5_ALG_MD5_DES_CBC
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} alg;
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 salt[8];
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t salt_len;
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	unsigned int iter_count;
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic enum pkcs5_alg pkcs5_get_alg(struct asn1_oid *oid)
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (oid->len == 7 &&
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    oid->oid[0] == 1 /* iso */ &&
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    oid->oid[1] == 2 /* member-body */ &&
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    oid->oid[2] == 840 /* us */ &&
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    oid->oid[3] == 113549 /* rsadsi */ &&
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    oid->oid[4] == 1 /* pkcs */ &&
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    oid->oid[5] == 5 /* pkcs-5 */ &&
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    oid->oid[6] == 3 /* pbeWithMD5AndDES-CBC */)
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return PKCS5_ALG_MD5_DES_CBC;
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return PKCS5_ALG_UNKNOWN;
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int pkcs5_get_params(const u8 *enc_alg, size_t enc_alg_len,
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    struct pkcs5_params *params)
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct asn1_hdr hdr;
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *enc_alg_end, *pos, *end;
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct asn1_oid oid;
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char obuf[80];
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* AlgorithmIdentifier */
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enc_alg_end = enc_alg + enc_alg_len;
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(params, 0, sizeof(*params));
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (asn1_get_oid(enc_alg, enc_alg_end - enc_alg, &oid, &pos)) {
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "PKCS #5: Failed to parse OID "
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "(algorithm)");
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	asn1_oid_to_str(&oid, obuf, sizeof(obuf));
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "PKCS #5: encryption algorithm %s", obuf);
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params->alg = pkcs5_get_alg(&oid);
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (params->alg == PKCS5_ALG_UNKNOWN) {
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "PKCS #5: unsupported encryption "
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "algorithm %s", obuf);
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * PKCS#5, Section 8
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * PBEParameter ::= SEQUENCE {
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 *   salt OCTET STRING SIZE(8),
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 *   iterationCount INTEGER }
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (asn1_get_next(pos, enc_alg_end - pos, &hdr) < 0 ||
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    hdr.class != ASN1_CLASS_UNIVERSAL ||
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    hdr.tag != ASN1_TAG_SEQUENCE) {
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "PKCS #5: Expected SEQUENCE "
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "(PBEParameter) - found class %d tag 0x%x",
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   hdr.class, hdr.tag);
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = hdr.payload;
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	end = hdr.payload + hdr.length;
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* salt OCTET STRING SIZE(8) */
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    hdr.class != ASN1_CLASS_UNIVERSAL ||
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    hdr.tag != ASN1_TAG_OCTETSTRING ||
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    hdr.length != 8) {
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "PKCS #5: Expected OCTETSTRING SIZE(8) "
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "(salt) - found class %d tag 0x%x size %d",
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   hdr.class, hdr.tag, hdr.length);
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = hdr.payload + hdr.length;
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(params->salt, hdr.payload, hdr.length);
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params->salt_len = hdr.length;
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_hexdump(MSG_DEBUG, "PKCS #5: salt",
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    params->salt, params->salt_len);
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* iterationCount INTEGER */
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_INTEGER) {
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "PKCS #5: Expected INTEGER - found "
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "class %d tag 0x%x", hdr.class, hdr.tag);
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hdr.length == 1)
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params->iter_count = *hdr.payload;
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (hdr.length == 2)
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params->iter_count = WPA_GET_BE16(hdr.payload);
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (hdr.length == 4)
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params->iter_count = WPA_GET_BE32(hdr.payload);
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else {
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_hexdump(MSG_DEBUG, "PKCS #5: Unsupported INTEGER value "
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    " (iterationCount)",
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    hdr.payload, hdr.length);
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "PKCS #5: iterationCount=0x%x",
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   params->iter_count);
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (params->iter_count == 0 || params->iter_count > 0xffff) {
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "PKCS #5: Unsupported "
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "iterationCount=0x%x", params->iter_count);
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct crypto_cipher * pkcs5_crypto_init(struct pkcs5_params *params,
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						const char *passwd)
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	unsigned int i;
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 hash[MD5_MAC_LEN];
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *addr[2];
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t len[2];
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (params->alg != PKCS5_ALG_MD5_DES_CBC)
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	addr[0] = (const u8 *) passwd;
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len[0] = os_strlen(passwd);
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	addr[1] = params->salt;
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len[1] = params->salt_len;
1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (md5_vector(2, addr, len, hash) < 0)
1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	addr[0] = hash;
1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len[0] = MD5_MAC_LEN;
1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 1; i < params->iter_count; i++) {
1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (md5_vector(1, addr, len, hash) < 0)
1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return NULL;
1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* TODO: DES key parity bits(?) */
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_hexdump_key(MSG_DEBUG, "PKCS #5: DES key", hash, 8);
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_hexdump_key(MSG_DEBUG, "PKCS #5: DES IV", hash + 8, 8);
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return crypto_cipher_init(CRYPTO_CIPHER_ALG_DES, hash + 8, hash, 8);
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu8 * pkcs5_decrypt(const u8 *enc_alg, size_t enc_alg_len,
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   const u8 *enc_data, size_t enc_data_len,
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   const char *passwd, size_t *data_len)
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct crypto_cipher *ctx;
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 *eb, pad;
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct pkcs5_params params;
1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	unsigned int i;
1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pkcs5_get_params(enc_alg, enc_alg_len, &params) < 0) {
1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "PKCS #5: Unsupported parameters");
1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ctx = pkcs5_crypto_init(&params, passwd);
1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ctx == NULL) {
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "PKCS #5: Failed to initialize crypto");
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* PKCS #5, Section 7 - Decryption process */
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (enc_data_len < 16 || enc_data_len % 8) {
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "PKCS #5: invalid length of ciphertext "
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "%d", (int) enc_data_len);
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		crypto_cipher_deinit(ctx);
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eb = os_malloc(enc_data_len);
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (eb == NULL) {
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		crypto_cipher_deinit(ctx);
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (crypto_cipher_decrypt(ctx, enc_data, eb, enc_data_len) < 0) {
2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "PKCS #5: Failed to decrypt EB");
2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		crypto_cipher_deinit(ctx);
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(eb);
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	crypto_cipher_deinit(ctx);
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pad = eb[enc_data_len - 1];
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pad > 8) {
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "PKCS #5: Invalid PS octet 0x%x", pad);
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(eb);
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = enc_data_len - pad; i < enc_data_len; i++) {
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (eb[i] != pad) {
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_hexdump(MSG_INFO, "PKCS #5: Invalid PS",
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    eb + enc_data_len - pad, pad);
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(eb);
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return NULL;
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_hexdump_key(MSG_MSGDUMP, "PKCS #5: message M (encrypted key)",
2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eb, enc_data_len - pad);
2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*data_len = enc_data_len - pad;
2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return eb;
2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
233