- unsigned char *pbuf, *salt, key[EVP_MAX_KEY_LENGTH];
- int saltlen, keylen, iter, plen;
- PBE2PARAM *pbe2 = NULL;
- const EVP_CIPHER *cipher;
- PBKDF2PARAM *kdf = NULL;
-
- pbuf = param->value.sequence->data;
- plen = param->value.sequence->length;
- if(!param || (param->type != V_ASN1_SEQUENCE) ||
- !(pbe2 = d2i_PBE2PARAM(NULL, &pbuf, plen))) {
- EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
- return 0;
- }
-
- /* See if we recognise the key derivation function */
-
- if(OBJ_obj2nid(pbe2->keyfunc->algorithm) != NID_id_pbkdf2) {
- EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
- EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION);
- goto err;
- }
-
- /* lets see if we recognise the encryption algorithm.
- */
-
- cipher = EVP_get_cipherbyname(
- OBJ_nid2sn(OBJ_obj2nid(pbe2->encryption->algorithm)));
-
- if(!cipher) {
- EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
- EVP_R_UNSUPPORTED_CIPHER);
- goto err;
- }
-
- /* Fixup cipher based on AlgorithmIdentifier */
- EVP_CipherInit(ctx, cipher, NULL, NULL, en_de);
- if(EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) {
- EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
- EVP_R_CIPHER_PARAMETER_ERROR);
- goto err;
- }
- keylen = EVP_CIPHER_CTX_key_length(ctx);
-
- /* Now decode key derivation function */
-
- pbuf = pbe2->keyfunc->parameter->value.sequence->data;
- plen = pbe2->keyfunc->parameter->value.sequence->length;
- if(!pbe2->keyfunc->parameter ||
- (pbe2->keyfunc->parameter->type != V_ASN1_SEQUENCE) ||
- !(kdf = d2i_PBKDF2PARAM(NULL, &pbuf, plen)) ) {
- EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR);
- goto err;
- }
-
- PBE2PARAM_free(pbe2);
- pbe2 = NULL;
-
- /* Now check the parameters of the kdf */
-
- if(kdf->keylength && (ASN1_INTEGER_get(kdf->keylength) != keylen)){
- EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
- EVP_R_UNSUPPORTED_KEYLENGTH);
- goto err;
- }
-
- if(kdf->prf && (OBJ_obj2nid(kdf->prf->algorithm) != NID_hmacWithSHA1)) {
- EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
- goto err;
- }
-
- if(kdf->salt->type != V_ASN1_OCTET_STRING) {
- EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
- EVP_R_UNSUPPORTED_SALT_TYPE);
- goto err;
- }
-
- /* it seems that its all OK */
- salt = kdf->salt->value.octet_string->data;
- saltlen = kdf->salt->value.octet_string->length;
- iter = ASN1_INTEGER_get(kdf->iter);
- PKCS5_PBKDF2_HMAC_SHA1(pass, passlen, salt, saltlen, iter, keylen, key);
- EVP_CipherInit(ctx, NULL, key, NULL, en_de);
- memset(key, 0, keylen);
- PBKDF2PARAM_free(kdf);
- return 1;
-
- err:
- PBE2PARAM_free(pbe2);
- PBKDF2PARAM_free(kdf);
- return 0;
+ const unsigned char *pbuf;
+ int plen;
+ PBE2PARAM *pbe2 = NULL;
+ const EVP_CIPHER *cipher;
+ EVP_PBE_KEYGEN *kdf;
+
+ int rv = 0;
+
+ if (param == NULL || param->type != V_ASN1_SEQUENCE ||
+ param->value.sequence == NULL) {
+ EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
+ goto err;
+ }
+
+ pbuf = param->value.sequence->data;
+ plen = param->value.sequence->length;
+ if (!(pbe2 = d2i_PBE2PARAM(NULL, &pbuf, plen))) {
+ EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
+ goto err;
+ }
+
+ /* See if we recognise the key derivation function */
+ if (!EVP_PBE_find(EVP_PBE_TYPE_KDF, OBJ_obj2nid(pbe2->keyfunc->algorithm),
+ NULL, NULL, &kdf)) {
+ EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
+ EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION);
+ goto err;
+ }
+
+ /*
+ * lets see if we recognise the encryption algorithm.
+ */
+
+ cipher = EVP_get_cipherbyobj(pbe2->encryption->algorithm);
+
+ if (!cipher) {
+ EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_CIPHER);
+ goto err;
+ }
+
+ /* Fixup cipher based on AlgorithmIdentifier */
+ if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de))
+ goto err;
+ if (EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) {
+ EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_CIPHER_PARAMETER_ERROR);
+ goto err;
+ }
+ rv = kdf(ctx, pass, passlen, pbe2->keyfunc->parameter, NULL, NULL, en_de);
+ err:
+ PBE2PARAM_free(pbe2);
+ return rv;