1c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* evp_pbe.c */
2c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * project 1999.
4c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */
5c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* ====================================================================
6480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
7c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
8c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Redistribution and use in source and binary forms, with or without
9c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * modification, are permitted provided that the following conditions
10c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * are met:
11c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
12c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 1. Redistributions of source code must retain the above copyright
13c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    notice, this list of conditions and the following disclaimer.
14c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
15c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 2. Redistributions in binary form must reproduce the above copyright
16c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    notice, this list of conditions and the following disclaimer in
17c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    the documentation and/or other materials provided with the
18c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    distribution.
19c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
20c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 3. All advertising materials mentioning features or use of this
21c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    software must display the following acknowledgment:
22c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    "This product includes software developed by the OpenSSL Project
23c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
25c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    endorse or promote products derived from this software without
27c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    prior written permission. For written permission, please contact
28c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    licensing@OpenSSL.org.
29c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
30c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 5. Products derived from this software may not be called "OpenSSL"
31c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    nor may "OpenSSL" appear in their names without prior written
32c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    permission of the OpenSSL Project.
33c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
34c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 6. Redistributions of any form whatsoever must retain the following
35c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    acknowledgment:
36c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    "This product includes software developed by the OpenSSL Project
37c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
39c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * OF THE POSSIBILITY OF SUCH DAMAGE.
51c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ====================================================================
52c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
53c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This product includes cryptographic software written by Eric Young
54c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * (eay@cryptsoft.com).  This product includes software written by Tim
55c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Hudson (tjh@cryptsoft.com).
56c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
57c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */
58c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
59c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <stdio.h>
60c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include "cryptlib.h"
61c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/evp.h>
62480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#include <openssl/pkcs12.h>
63c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/x509.h>
642c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#include "evp_locl.h"
65c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
66c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Password based encryption (PBE) functions */
67c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
68480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgDECLARE_STACK_OF(EVP_PBE_CTL)
69480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic STACK_OF(EVP_PBE_CTL) *pbe_algs;
70c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
71c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Setup a cipher context from a PBE algorithm */
72c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
73480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgtypedef struct
74480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
75480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int pbe_type;
76480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int pbe_nid;
77480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int cipher_nid;
78480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int md_nid;
79480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	EVP_PBE_KEYGEN *keygen;
80480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	} EVP_PBE_CTL;
81c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
82480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic const EVP_PBE_CTL builtin_pbe[] =
83480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
84480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndDES_CBC,
85480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen},
86480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndDES_CBC,
87480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen},
88480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC,
89480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen},
90c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
912c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifndef OPENSSL_NO_HMAC
922c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	{EVP_PBE_TYPE_OUTER, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen},
932c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif
942c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org
95480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4,
96480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			NID_rc4, NID_sha1, PKCS12_PBE_keyivgen},
97480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4,
98480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen},
99480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
100480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		 	NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen},
101480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And2_Key_TripleDES_CBC,
102480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen},
103480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC2_CBC,
104480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen},
105480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC2_CBC,
106480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen},
107480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
108480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#ifndef OPENSSL_NO_HMAC
109480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen},
110480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#endif
111480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndRC2_CBC,
112480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen},
113480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndRC2_CBC,
114480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen},
115480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndDES_CBC,
116480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen},
117480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
118480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
119480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA1, -1, NID_sha1, 0},
120480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{EVP_PBE_TYPE_PRF, NID_hmacWithMD5, -1, NID_md5, 0},
121480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA224, -1, NID_sha224, 0},
122480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA256, -1, NID_sha256, 0},
123480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA384, -1, NID_sha384, 0},
124480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA512, -1, NID_sha512, 0},
125480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{EVP_PBE_TYPE_PRF, NID_id_HMACGostR3411_94, -1, NID_id_GostR3411_94, 0},
126480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	};
127480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
128480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#ifdef TEST
129480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgint main(int argc, char **argv)
130480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
131480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int i, nid_md, nid_cipher;
132480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	EVP_PBE_CTL *tpbe, *tpbe2;
133480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/*OpenSSL_add_all_algorithms();*/
134480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
135480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	for (i = 0; i < sizeof(builtin_pbe)/sizeof(EVP_PBE_CTL); i++)
136480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
137480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		tpbe = builtin_pbe + i;
138480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		fprintf(stderr, "%d %d %s ", tpbe->pbe_type, tpbe->pbe_nid,
139480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org						OBJ_nid2sn(tpbe->pbe_nid));
140480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (EVP_PBE_find(tpbe->pbe_type, tpbe->pbe_nid,
141480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org					&nid_cipher ,&nid_md,0))
142480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			fprintf(stderr, "Found %s %s\n",
143480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org					OBJ_nid2sn(nid_cipher),
144480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org					OBJ_nid2sn(nid_md));
145480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		else
146480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			fprintf(stderr, "Find ERROR!!\n");
147480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
148480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
149480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return 0;
150480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
151480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#endif
152480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
153480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
154480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
155480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgint EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
156480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		       ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de)
157480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
158480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	const EVP_CIPHER *cipher;
159480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	const EVP_MD *md;
160480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int cipher_nid, md_nid;
161480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	EVP_PBE_KEYGEN *keygen;
162c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
163480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj),
164480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org					&cipher_nid, &md_nid, &keygen))
165480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
166c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		char obj_tmp[80];
167c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_PBE_ALGORITHM);
168c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (!pbe_obj) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp);
169c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		else i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj);
170c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ERR_add_error_data(2, "TYPE=", obj_tmp);
171c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return 0;
172480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
173480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
174480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if(!pass)
175480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		passlen = 0;
176480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else if (passlen == -1)
177480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		passlen = strlen(pass);
178480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
179480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (cipher_nid == -1)
180480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		cipher = NULL;
181480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else
182480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
183480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		cipher = EVP_get_cipherbynid(cipher_nid);
184480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!cipher)
185480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
186480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_CIPHER);
187480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
188480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
189480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
190480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
191480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (md_nid == -1)
192480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		md = NULL;
193480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else
194480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
195480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		md = EVP_get_digestbynid(md_nid);
196480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!md)
197480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
198480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_DIGEST);
199480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
200480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
201480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
202480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
203480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!keygen(ctx, pass, passlen, param, cipher, md, en_de))
204480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
205c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_KEYGEN_FAILURE);
206c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return 0;
207480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
208c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return 1;
209c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org}
210c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
211480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgDECLARE_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2);
212480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
213480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int pbe2_cmp(const EVP_PBE_CTL *pbe1, const EVP_PBE_CTL *pbe2)
214480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
215480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int ret = pbe1->pbe_type - pbe2->pbe_type;
216480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (ret)
217480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return ret;
218480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else
219480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return pbe1->pbe_nid - pbe2->pbe_nid;
220480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
221480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
222480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgIMPLEMENT_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2);
223480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
224480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int pbe_cmp(const EVP_PBE_CTL * const *a, const EVP_PBE_CTL * const *b)
225480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
226480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int ret = (*a)->pbe_type - (*b)->pbe_type;
227480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (ret)
228480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return ret;
229480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else
230480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return (*a)->pbe_nid - (*b)->pbe_nid;
231480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
232c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
233c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Add a PBE algorithm */
234c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
235480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgint EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid,
236480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			 EVP_PBE_KEYGEN *keygen)
237480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
238c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	EVP_PBE_CTL *pbe_tmp;
239480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!pbe_algs)
240480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		pbe_algs = sk_EVP_PBE_CTL_new(pbe_cmp);
241480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!(pbe_tmp = (EVP_PBE_CTL*) OPENSSL_malloc (sizeof(EVP_PBE_CTL))))
242480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
243480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		EVPerr(EVP_F_EVP_PBE_ALG_ADD_TYPE,ERR_R_MALLOC_FAILURE);
244c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return 0;
245480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
246480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	pbe_tmp->pbe_type = pbe_type;
247480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	pbe_tmp->pbe_nid = pbe_nid;
248480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	pbe_tmp->cipher_nid = cipher_nid;
249480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	pbe_tmp->md_nid = md_nid;
250c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	pbe_tmp->keygen = keygen;
251480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
252480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
253480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	sk_EVP_PBE_CTL_push (pbe_algs, pbe_tmp);
254c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return 1;
255480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
256480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
257480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgint EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
258480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		    EVP_PBE_KEYGEN *keygen)
259480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
260480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int cipher_nid, md_nid;
261480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (cipher)
262480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		cipher_nid = EVP_CIPHER_type(cipher);
263480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else
264480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		cipher_nid = -1;
265480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (md)
266480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		md_nid = EVP_MD_type(md);
267480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else
268480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		md_nid = -1;
269480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
270480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return EVP_PBE_alg_add_type(EVP_PBE_TYPE_OUTER, nid,
271480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org					cipher_nid, md_nid, keygen);
272480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
273480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
274480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgint EVP_PBE_find(int type, int pbe_nid,
275480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		 int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen)
276480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
277480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	EVP_PBE_CTL *pbetmp = NULL, pbelu;
278480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int i;
279480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (pbe_nid == NID_undef)
280480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 0;
281480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
282480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	pbelu.pbe_type = type;
283480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	pbelu.pbe_nid = pbe_nid;
284480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
285480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (pbe_algs)
286480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
287480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu);
288480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (i != -1)
289480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			pbetmp = sk_EVP_PBE_CTL_value (pbe_algs, i);
290480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
291480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (pbetmp == NULL)
292480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
293480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		pbetmp = OBJ_bsearch_pbe2(&pbelu, builtin_pbe,
294480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				     sizeof(builtin_pbe)/sizeof(EVP_PBE_CTL));
295480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
296480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (pbetmp == NULL)
297480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 0;
298480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (pcnid)
299480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		*pcnid = pbetmp->cipher_nid;
300480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (pmnid)
301480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		*pmnid = pbetmp->md_nid;
302480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (pkeygen)
303480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		*pkeygen = pbetmp->keygen;
304480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return 1;
305480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
306480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
307480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic void free_evp_pbe_ctl(EVP_PBE_CTL *pbe)
308480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	 {
309480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	 OPENSSL_freeFunc(pbe);
310480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	 }
311c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
312c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgvoid EVP_PBE_cleanup(void)
313480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
314480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	sk_EVP_PBE_CTL_pop_free(pbe_algs, free_evp_pbe_ctl);
315c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	pbe_algs = NULL;
316480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
317