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, ¶ms) < 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(¶ms, 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