1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* evp_pbe.c */
2e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * project 1999.
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ====================================================================
6221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the documentation and/or other materials provided with the
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    distribution.
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    software must display the following acknowledgment:
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    endorse or promote products derived from this software without
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    prior written permission. For written permission, please contact
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    licensing@OpenSSL.org.
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL"
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    nor may "OpenSSL" appear in their names without prior written
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    permission of the OpenSSL Project.
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    acknowledgment:
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE.
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ====================================================================
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com).  This product includes software written by Tim
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com).
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdio.h>
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "cryptlib.h"
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/evp.h>
62221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <openssl/pkcs12.h>
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/x509.h>
64392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include "evp_locl.h"
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Password based encryption (PBE) functions */
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
68221304ee937bc0910948a8be1320cb8cc4eb6d36Brian CarlstromDECLARE_STACK_OF(EVP_PBE_CTL)
69221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic STACK_OF(EVP_PBE_CTL) *pbe_algs;
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Setup a cipher context from a PBE algorithm */
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
73221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromtypedef struct
74221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
75221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int pbe_type;
76221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int pbe_nid;
77221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int cipher_nid;
78221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int md_nid;
79221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_PBE_KEYGEN *keygen;
80221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	} EVP_PBE_CTL;
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
82221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic const EVP_PBE_CTL builtin_pbe[] =
83221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
84221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndDES_CBC,
85221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen},
86221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndDES_CBC,
87221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen},
88221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC,
89221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen},
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
91392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_HMAC
92392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{EVP_PBE_TYPE_OUTER, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen},
93392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
94392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
95221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4,
96221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			NID_rc4, NID_sha1, PKCS12_PBE_keyivgen},
97221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4,
98221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen},
99221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
100221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		 	NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen},
101221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And2_Key_TripleDES_CBC,
102221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen},
103221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC2_CBC,
104221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen},
105221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC2_CBC,
106221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen},
107221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
108221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifndef OPENSSL_NO_HMAC
109221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen},
110221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
111221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndRC2_CBC,
112221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen},
113221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndRC2_CBC,
114221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen},
115221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndDES_CBC,
116221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen},
117221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
118221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
119221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA1, -1, NID_sha1, 0},
120221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{EVP_PBE_TYPE_PRF, NID_hmacWithMD5, -1, NID_md5, 0},
121221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA224, -1, NID_sha224, 0},
122221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA256, -1, NID_sha256, 0},
123221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA384, -1, NID_sha384, 0},
124221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA512, -1, NID_sha512, 0},
125221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{EVP_PBE_TYPE_PRF, NID_id_HMACGostR3411_94, -1, NID_id_GostR3411_94, 0},
126221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	};
127221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
128221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifdef TEST
129221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint main(int argc, char **argv)
130221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
131221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int i, nid_md, nid_cipher;
132221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_PBE_CTL *tpbe, *tpbe2;
133221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/*OpenSSL_add_all_algorithms();*/
134221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
135221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	for (i = 0; i < sizeof(builtin_pbe)/sizeof(EVP_PBE_CTL); i++)
136221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
137221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		tpbe = builtin_pbe + i;
138221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		fprintf(stderr, "%d %d %s ", tpbe->pbe_type, tpbe->pbe_nid,
139221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom						OBJ_nid2sn(tpbe->pbe_nid));
140221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (EVP_PBE_find(tpbe->pbe_type, tpbe->pbe_nid,
141221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					&nid_cipher ,&nid_md,0))
142221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			fprintf(stderr, "Found %s %s\n",
143221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					OBJ_nid2sn(nid_cipher),
144221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					OBJ_nid2sn(nid_md));
145221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else
146221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			fprintf(stderr, "Find ERROR!!\n");
147221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
148221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
149221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 0;
150221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
151221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
152221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
153221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
154221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
155221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
156221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		       ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de)
157221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
158221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	const EVP_CIPHER *cipher;
159221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	const EVP_MD *md;
160221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int cipher_nid, md_nid;
161221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_PBE_KEYGEN *keygen;
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
163221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj),
164221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					&cipher_nid, &md_nid, &keygen))
165221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		char obj_tmp[80];
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_PBE_ALGORITHM);
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!pbe_obj) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp);
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj);
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ERR_add_error_data(2, "TYPE=", obj_tmp);
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
172221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
173221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
174221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if(!pass)
175221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		passlen = 0;
176221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else if (passlen == -1)
177221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		passlen = strlen(pass);
178221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
179221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (cipher_nid == -1)
180221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		cipher = NULL;
181221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else
182221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
183221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		cipher = EVP_get_cipherbynid(cipher_nid);
184221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (!cipher)
185221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
186221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_CIPHER);
187221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return 0;
188221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
189221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
190221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
191221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (md_nid == -1)
192221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		md = NULL;
193221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else
194221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
195221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		md = EVP_get_digestbynid(md_nid);
196221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (!md)
197221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
198221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_DIGEST);
199221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return 0;
200221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
201221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
202221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
203221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!keygen(ctx, pass, passlen, param, cipher, md, en_de))
204221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_KEYGEN_FAILURE);
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
207221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
211221304ee937bc0910948a8be1320cb8cc4eb6d36Brian CarlstromDECLARE_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2);
212221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
213221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int pbe2_cmp(const EVP_PBE_CTL *pbe1, const EVP_PBE_CTL *pbe2)
214221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
215221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int ret = pbe1->pbe_type - pbe2->pbe_type;
216221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ret)
217221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return ret;
218221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else
219221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return pbe1->pbe_nid - pbe2->pbe_nid;
220221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
221221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
222221304ee937bc0910948a8be1320cb8cc4eb6d36Brian CarlstromIMPLEMENT_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2);
223221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
224221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int pbe_cmp(const EVP_PBE_CTL * const *a, const EVP_PBE_CTL * const *b)
225221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
226221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int ret = (*a)->pbe_type - (*b)->pbe_type;
227221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ret)
228221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return ret;
229221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else
230221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return (*a)->pbe_nid - (*b)->pbe_nid;
231221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Add a PBE algorithm */
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
235221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid,
236221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			 EVP_PBE_KEYGEN *keygen)
237221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_PBE_CTL *pbe_tmp;
239221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!pbe_algs)
240221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		pbe_algs = sk_EVP_PBE_CTL_new(pbe_cmp);
241221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!(pbe_tmp = (EVP_PBE_CTL*) OPENSSL_malloc (sizeof(EVP_PBE_CTL))))
242221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
243221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PBE_ALG_ADD_TYPE,ERR_R_MALLOC_FAILURE);
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
245221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
246221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pbe_tmp->pbe_type = pbe_type;
247221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pbe_tmp->pbe_nid = pbe_nid;
248221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pbe_tmp->cipher_nid = cipher_nid;
249221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pbe_tmp->md_nid = md_nid;
250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	pbe_tmp->keygen = keygen;
251221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
252221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
253221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sk_EVP_PBE_CTL_push (pbe_algs, pbe_tmp);
254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
255221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
256221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
257221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
258221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		    EVP_PBE_KEYGEN *keygen)
259221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
260221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int cipher_nid, md_nid;
261221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (cipher)
262c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root		cipher_nid = EVP_CIPHER_nid(cipher);
263221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else
264221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		cipher_nid = -1;
265221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (md)
266221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		md_nid = EVP_MD_type(md);
267221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else
268221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		md_nid = -1;
269221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
270221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return EVP_PBE_alg_add_type(EVP_PBE_TYPE_OUTER, nid,
271221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					cipher_nid, md_nid, keygen);
272221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
273221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
274221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint EVP_PBE_find(int type, int pbe_nid,
275221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		 int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen)
276221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
277221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_PBE_CTL *pbetmp = NULL, pbelu;
278221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int i;
279221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (pbe_nid == NID_undef)
280221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
281221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
282221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pbelu.pbe_type = type;
283221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pbelu.pbe_nid = pbe_nid;
284221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
285221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (pbe_algs)
286221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
287221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu);
288221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (i != -1)
289221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			pbetmp = sk_EVP_PBE_CTL_value (pbe_algs, i);
290221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
291221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (pbetmp == NULL)
292221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
293221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		pbetmp = OBJ_bsearch_pbe2(&pbelu, builtin_pbe,
294221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				     sizeof(builtin_pbe)/sizeof(EVP_PBE_CTL));
295221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
296221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (pbetmp == NULL)
297221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
298221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (pcnid)
299221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		*pcnid = pbetmp->cipher_nid;
300221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (pmnid)
301221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		*pmnid = pbetmp->md_nid;
302221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (pkeygen)
303221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		*pkeygen = pbetmp->keygen;
304221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 1;
305221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
306221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
307221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void free_evp_pbe_ctl(EVP_PBE_CTL *pbe)
308221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	 {
309221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	 OPENSSL_freeFunc(pbe);
310221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	 }
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid EVP_PBE_cleanup(void)
313221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
314221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sk_EVP_PBE_CTL_pop_free(pbe_algs, free_evp_pbe_ctl);
315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	pbe_algs = NULL;
316221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
317