2 * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
11 #include "internal/cryptlib.h"
12 #include <openssl/evp.h>
13 #include <openssl/pkcs12.h>
14 #include <openssl/x509.h>
17 /* Password based encryption (PBE) functions */
19 /* Setup a cipher context from a PBE algorithm */
26 EVP_PBE_KEYGEN
*keygen
;
29 static STACK_OF(EVP_PBE_CTL
) *pbe_algs
;
31 static const EVP_PBE_CTL builtin_pbe
[] = {
32 {EVP_PBE_TYPE_OUTER
, NID_pbeWithMD2AndDES_CBC
,
33 NID_des_cbc
, NID_md2
, PKCS5_PBE_keyivgen
},
34 {EVP_PBE_TYPE_OUTER
, NID_pbeWithMD5AndDES_CBC
,
35 NID_des_cbc
, NID_md5
, PKCS5_PBE_keyivgen
},
36 {EVP_PBE_TYPE_OUTER
, NID_pbeWithSHA1AndRC2_CBC
,
37 NID_rc2_64_cbc
, NID_sha1
, PKCS5_PBE_keyivgen
},
39 {EVP_PBE_TYPE_OUTER
, NID_id_pbkdf2
, -1, -1, PKCS5_v2_PBKDF2_keyivgen
},
41 {EVP_PBE_TYPE_OUTER
, NID_pbe_WithSHA1And128BitRC4
,
42 NID_rc4
, NID_sha1
, PKCS12_PBE_keyivgen
},
43 {EVP_PBE_TYPE_OUTER
, NID_pbe_WithSHA1And40BitRC4
,
44 NID_rc4_40
, NID_sha1
, PKCS12_PBE_keyivgen
},
45 {EVP_PBE_TYPE_OUTER
, NID_pbe_WithSHA1And3_Key_TripleDES_CBC
,
46 NID_des_ede3_cbc
, NID_sha1
, PKCS12_PBE_keyivgen
},
47 {EVP_PBE_TYPE_OUTER
, NID_pbe_WithSHA1And2_Key_TripleDES_CBC
,
48 NID_des_ede_cbc
, NID_sha1
, PKCS12_PBE_keyivgen
},
49 {EVP_PBE_TYPE_OUTER
, NID_pbe_WithSHA1And128BitRC2_CBC
,
50 NID_rc2_cbc
, NID_sha1
, PKCS12_PBE_keyivgen
},
51 {EVP_PBE_TYPE_OUTER
, NID_pbe_WithSHA1And40BitRC2_CBC
,
52 NID_rc2_40_cbc
, NID_sha1
, PKCS12_PBE_keyivgen
},
54 {EVP_PBE_TYPE_OUTER
, NID_pbes2
, -1, -1, PKCS5_v2_PBE_keyivgen
},
56 {EVP_PBE_TYPE_OUTER
, NID_pbeWithMD2AndRC2_CBC
,
57 NID_rc2_64_cbc
, NID_md2
, PKCS5_PBE_keyivgen
},
58 {EVP_PBE_TYPE_OUTER
, NID_pbeWithMD5AndRC2_CBC
,
59 NID_rc2_64_cbc
, NID_md5
, PKCS5_PBE_keyivgen
},
60 {EVP_PBE_TYPE_OUTER
, NID_pbeWithSHA1AndDES_CBC
,
61 NID_des_cbc
, NID_sha1
, PKCS5_PBE_keyivgen
},
63 {EVP_PBE_TYPE_PRF
, NID_hmacWithSHA1
, -1, NID_sha1
, 0},
64 {EVP_PBE_TYPE_PRF
, NID_hmacWithMD5
, -1, NID_md5
, 0},
65 {EVP_PBE_TYPE_PRF
, NID_hmacWithSHA224
, -1, NID_sha224
, 0},
66 {EVP_PBE_TYPE_PRF
, NID_hmacWithSHA256
, -1, NID_sha256
, 0},
67 {EVP_PBE_TYPE_PRF
, NID_hmacWithSHA384
, -1, NID_sha384
, 0},
68 {EVP_PBE_TYPE_PRF
, NID_hmacWithSHA512
, -1, NID_sha512
, 0},
69 {EVP_PBE_TYPE_PRF
, NID_id_HMACGostR3411_94
, -1, NID_id_GostR3411_94
, 0},
70 {EVP_PBE_TYPE_PRF
, NID_id_tc26_hmac_gost_3411_2012_256
, -1,
71 NID_id_GostR3411_2012_256
, 0},
72 {EVP_PBE_TYPE_PRF
, NID_id_tc26_hmac_gost_3411_2012_512
, -1,
73 NID_id_GostR3411_2012_512
, 0},
74 {EVP_PBE_TYPE_KDF
, NID_id_pbkdf2
, -1, -1, PKCS5_v2_PBKDF2_keyivgen
},
75 #ifndef OPENSSL_NO_SCRYPT
76 {EVP_PBE_TYPE_KDF
, NID_id_scrypt
, -1, -1, PKCS5_v2_scrypt_keyivgen
}
80 int EVP_PBE_CipherInit(ASN1_OBJECT
*pbe_obj
, const char *pass
, int passlen
,
81 ASN1_TYPE
*param
, EVP_CIPHER_CTX
*ctx
, int en_de
)
83 const EVP_CIPHER
*cipher
;
85 int cipher_nid
, md_nid
;
86 EVP_PBE_KEYGEN
*keygen
;
88 if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER
, OBJ_obj2nid(pbe_obj
),
89 &cipher_nid
, &md_nid
, &keygen
)) {
91 EVPerr(EVP_F_EVP_PBE_CIPHERINIT
, EVP_R_UNKNOWN_PBE_ALGORITHM
);
93 strcpy(obj_tmp
, "NULL");
95 i2t_ASN1_OBJECT(obj_tmp
, sizeof obj_tmp
, pbe_obj
);
96 ERR_add_error_data(2, "TYPE=", obj_tmp
);
102 else if (passlen
== -1)
103 passlen
= strlen(pass
);
105 if (cipher_nid
== -1)
108 cipher
= EVP_get_cipherbynid(cipher_nid
);
110 EVPerr(EVP_F_EVP_PBE_CIPHERINIT
, EVP_R_UNKNOWN_CIPHER
);
118 md
= EVP_get_digestbynid(md_nid
);
120 EVPerr(EVP_F_EVP_PBE_CIPHERINIT
, EVP_R_UNKNOWN_DIGEST
);
125 if (!keygen(ctx
, pass
, passlen
, param
, cipher
, md
, en_de
)) {
126 EVPerr(EVP_F_EVP_PBE_CIPHERINIT
, EVP_R_KEYGEN_FAILURE
);
132 DECLARE_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL
, EVP_PBE_CTL
, pbe2
);
134 static int pbe2_cmp(const EVP_PBE_CTL
*pbe1
, const EVP_PBE_CTL
*pbe2
)
136 int ret
= pbe1
->pbe_type
- pbe2
->pbe_type
;
140 return pbe1
->pbe_nid
- pbe2
->pbe_nid
;
143 IMPLEMENT_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL
, EVP_PBE_CTL
, pbe2
);
145 static int pbe_cmp(const EVP_PBE_CTL
*const *a
, const EVP_PBE_CTL
*const *b
)
147 int ret
= (*a
)->pbe_type
- (*b
)->pbe_type
;
151 return (*a
)->pbe_nid
- (*b
)->pbe_nid
;
154 /* Add a PBE algorithm */
156 int EVP_PBE_alg_add_type(int pbe_type
, int pbe_nid
, int cipher_nid
,
157 int md_nid
, EVP_PBE_KEYGEN
*keygen
)
159 EVP_PBE_CTL
*pbe_tmp
;
161 if (pbe_algs
== NULL
) {
162 pbe_algs
= sk_EVP_PBE_CTL_new(pbe_cmp
);
163 if (pbe_algs
== NULL
)
167 if ((pbe_tmp
= OPENSSL_malloc(sizeof(*pbe_tmp
))) == NULL
)
170 pbe_tmp
->pbe_type
= pbe_type
;
171 pbe_tmp
->pbe_nid
= pbe_nid
;
172 pbe_tmp
->cipher_nid
= cipher_nid
;
173 pbe_tmp
->md_nid
= md_nid
;
174 pbe_tmp
->keygen
= keygen
;
176 if (!sk_EVP_PBE_CTL_push(pbe_algs
, pbe_tmp
)) {
177 OPENSSL_free(pbe_tmp
);
183 EVPerr(EVP_F_EVP_PBE_ALG_ADD_TYPE
, ERR_R_MALLOC_FAILURE
);
187 int EVP_PBE_alg_add(int nid
, const EVP_CIPHER
*cipher
, const EVP_MD
*md
,
188 EVP_PBE_KEYGEN
*keygen
)
190 int cipher_nid
, md_nid
;
193 cipher_nid
= EVP_CIPHER_nid(cipher
);
197 md_nid
= EVP_MD_type(md
);
201 return EVP_PBE_alg_add_type(EVP_PBE_TYPE_OUTER
, nid
,
202 cipher_nid
, md_nid
, keygen
);
205 int EVP_PBE_find(int type
, int pbe_nid
,
206 int *pcnid
, int *pmnid
, EVP_PBE_KEYGEN
**pkeygen
)
208 EVP_PBE_CTL
*pbetmp
= NULL
, pbelu
;
210 if (pbe_nid
== NID_undef
)
213 pbelu
.pbe_type
= type
;
214 pbelu
.pbe_nid
= pbe_nid
;
217 i
= sk_EVP_PBE_CTL_find(pbe_algs
, &pbelu
);
219 pbetmp
= sk_EVP_PBE_CTL_value(pbe_algs
, i
);
221 if (pbetmp
== NULL
) {
222 pbetmp
= OBJ_bsearch_pbe2(&pbelu
, builtin_pbe
, OSSL_NELEM(builtin_pbe
));
227 *pcnid
= pbetmp
->cipher_nid
;
229 *pmnid
= pbetmp
->md_nid
;
231 *pkeygen
= pbetmp
->keygen
;
235 static void free_evp_pbe_ctl(EVP_PBE_CTL
*pbe
)
240 void EVP_PBE_cleanup(void)
242 sk_EVP_PBE_CTL_pop_free(pbe_algs
, free_evp_pbe_ctl
);
246 int EVP_PBE_get(int *ptype
, int *ppbe_nid
, size_t num
)
248 const EVP_PBE_CTL
*tpbe
;
250 if (num
>= OSSL_NELEM(builtin_pbe
))
253 tpbe
= builtin_pbe
+ num
;
255 *ptype
= tpbe
->pbe_type
;
257 *ppbe_nid
= tpbe
->pbe_nid
;