155714Skris/* evp_pbe.c */ 2296341Sdelphij/* 3296341Sdelphij * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 4296341Sdelphij * 1999. 555714Skris */ 655714Skris/* ==================================================================== 7238405Sjkim * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. 855714Skris * 955714Skris * Redistribution and use in source and binary forms, with or without 1055714Skris * modification, are permitted provided that the following conditions 1155714Skris * are met: 1255714Skris * 1355714Skris * 1. Redistributions of source code must retain the above copyright 14296341Sdelphij * notice, this list of conditions and the following disclaimer. 1555714Skris * 1655714Skris * 2. Redistributions in binary form must reproduce the above copyright 1755714Skris * notice, this list of conditions and the following disclaimer in 1855714Skris * the documentation and/or other materials provided with the 1955714Skris * distribution. 2055714Skris * 2155714Skris * 3. All advertising materials mentioning features or use of this 2255714Skris * software must display the following acknowledgment: 2355714Skris * "This product includes software developed by the OpenSSL Project 2455714Skris * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 2555714Skris * 2655714Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 2755714Skris * endorse or promote products derived from this software without 2855714Skris * prior written permission. For written permission, please contact 2955714Skris * licensing@OpenSSL.org. 3055714Skris * 3155714Skris * 5. Products derived from this software may not be called "OpenSSL" 3255714Skris * nor may "OpenSSL" appear in their names without prior written 3355714Skris * permission of the OpenSSL Project. 3455714Skris * 3555714Skris * 6. Redistributions of any form whatsoever must retain the following 3655714Skris * acknowledgment: 3755714Skris * "This product includes software developed by the OpenSSL Project 3855714Skris * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 3955714Skris * 4055714Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 4155714Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4255714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 4355714Skris * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 4455714Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4555714Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4655714Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 4755714Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4955714Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 5055714Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 5155714Skris * OF THE POSSIBILITY OF SUCH DAMAGE. 5255714Skris * ==================================================================== 5355714Skris * 5455714Skris * This product includes cryptographic software written by Eric Young 5555714Skris * (eay@cryptsoft.com). This product includes software written by Tim 5655714Skris * Hudson (tjh@cryptsoft.com). 5755714Skris * 5855714Skris */ 5955714Skris 6055714Skris#include <stdio.h> 61109998Smarkm#include "cryptlib.h" 6255714Skris#include <openssl/evp.h> 63238405Sjkim#include <openssl/pkcs12.h> 6455714Skris#include <openssl/x509.h> 65238405Sjkim#include "evp_locl.h" 6655714Skris 6755714Skris/* Password based encryption (PBE) functions */ 6855714Skris 69238405SjkimDECLARE_STACK_OF(EVP_PBE_CTL) 70238405Sjkimstatic STACK_OF(EVP_PBE_CTL) *pbe_algs; 7155714Skris 7255714Skris/* Setup a cipher context from a PBE algorithm */ 7355714Skris 74296341Sdelphijtypedef struct { 75296341Sdelphij int pbe_type; 76296341Sdelphij int pbe_nid; 77296341Sdelphij int cipher_nid; 78296341Sdelphij int md_nid; 79296341Sdelphij EVP_PBE_KEYGEN *keygen; 80296341Sdelphij} EVP_PBE_CTL; 8155714Skris 82296341Sdelphijstatic const EVP_PBE_CTL builtin_pbe[] = { 83296341Sdelphij {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndDES_CBC, 84296341Sdelphij NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen}, 85296341Sdelphij {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndDES_CBC, 86296341Sdelphij NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen}, 87296341Sdelphij {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC, 88296341Sdelphij NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen}, 89238405Sjkim 90238405Sjkim#ifndef OPENSSL_NO_HMAC 91296341Sdelphij {EVP_PBE_TYPE_OUTER, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen}, 92238405Sjkim#endif 93238405Sjkim 94296341Sdelphij {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4, 95296341Sdelphij NID_rc4, NID_sha1, PKCS12_PBE_keyivgen}, 96296341Sdelphij {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4, 97296341Sdelphij NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen}, 98296341Sdelphij {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 99296341Sdelphij NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen}, 100296341Sdelphij {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And2_Key_TripleDES_CBC, 101296341Sdelphij NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen}, 102296341Sdelphij {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC2_CBC, 103296341Sdelphij NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen}, 104296341Sdelphij {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC2_CBC, 105296341Sdelphij NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen}, 106238405Sjkim 107238405Sjkim#ifndef OPENSSL_NO_HMAC 108296341Sdelphij {EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen}, 109238405Sjkim#endif 110296341Sdelphij {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndRC2_CBC, 111296341Sdelphij NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen}, 112296341Sdelphij {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndRC2_CBC, 113296341Sdelphij NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen}, 114296341Sdelphij {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndDES_CBC, 115296341Sdelphij NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen}, 116238405Sjkim 117296341Sdelphij {EVP_PBE_TYPE_PRF, NID_hmacWithSHA1, -1, NID_sha1, 0}, 118296341Sdelphij {EVP_PBE_TYPE_PRF, NID_hmacWithMD5, -1, NID_md5, 0}, 119296341Sdelphij {EVP_PBE_TYPE_PRF, NID_hmacWithSHA224, -1, NID_sha224, 0}, 120296341Sdelphij {EVP_PBE_TYPE_PRF, NID_hmacWithSHA256, -1, NID_sha256, 0}, 121296341Sdelphij {EVP_PBE_TYPE_PRF, NID_hmacWithSHA384, -1, NID_sha384, 0}, 122296341Sdelphij {EVP_PBE_TYPE_PRF, NID_hmacWithSHA512, -1, NID_sha512, 0}, 123296341Sdelphij {EVP_PBE_TYPE_PRF, NID_id_HMACGostR3411_94, -1, NID_id_GostR3411_94, 0}, 124296341Sdelphij}; 125238405Sjkim 126238405Sjkim#ifdef TEST 127238405Sjkimint main(int argc, char **argv) 128296341Sdelphij{ 129296341Sdelphij int i, nid_md, nid_cipher; 130296341Sdelphij EVP_PBE_CTL *tpbe, *tpbe2; 131296341Sdelphij /* 132296341Sdelphij * OpenSSL_add_all_algorithms(); 133296341Sdelphij */ 134238405Sjkim 135296341Sdelphij for (i = 0; i < sizeof(builtin_pbe) / sizeof(EVP_PBE_CTL); i++) { 136296341Sdelphij tpbe = builtin_pbe + i; 137296341Sdelphij fprintf(stderr, "%d %d %s ", tpbe->pbe_type, tpbe->pbe_nid, 138296341Sdelphij OBJ_nid2sn(tpbe->pbe_nid)); 139296341Sdelphij if (EVP_PBE_find(tpbe->pbe_type, tpbe->pbe_nid, 140296341Sdelphij &nid_cipher, &nid_md, 0)) 141296341Sdelphij fprintf(stderr, "Found %s %s\n", 142296341Sdelphij OBJ_nid2sn(nid_cipher), OBJ_nid2sn(nid_md)); 143296341Sdelphij else 144296341Sdelphij fprintf(stderr, "Find ERROR!!\n"); 145296341Sdelphij } 146238405Sjkim 147296341Sdelphij return 0; 148296341Sdelphij} 149238405Sjkim#endif 150238405Sjkim 151160814Ssimonint EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, 152296341Sdelphij ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de) 153296341Sdelphij{ 154296341Sdelphij const EVP_CIPHER *cipher; 155296341Sdelphij const EVP_MD *md; 156296341Sdelphij int cipher_nid, md_nid; 157296341Sdelphij EVP_PBE_KEYGEN *keygen; 15855714Skris 159296341Sdelphij if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj), 160296341Sdelphij &cipher_nid, &md_nid, &keygen)) { 161296341Sdelphij char obj_tmp[80]; 162296341Sdelphij EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_PBE_ALGORITHM); 163296341Sdelphij if (!pbe_obj) 164296341Sdelphij BUF_strlcpy(obj_tmp, "NULL", sizeof obj_tmp); 165296341Sdelphij else 166296341Sdelphij i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj); 167296341Sdelphij ERR_add_error_data(2, "TYPE=", obj_tmp); 168296341Sdelphij return 0; 169296341Sdelphij } 17055714Skris 171296341Sdelphij if (!pass) 172296341Sdelphij passlen = 0; 173296341Sdelphij else if (passlen == -1) 174296341Sdelphij passlen = strlen(pass); 17555714Skris 176296341Sdelphij if (cipher_nid == -1) 177296341Sdelphij cipher = NULL; 178296341Sdelphij else { 179296341Sdelphij cipher = EVP_get_cipherbynid(cipher_nid); 180296341Sdelphij if (!cipher) { 181296341Sdelphij EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_CIPHER); 182296341Sdelphij return 0; 183296341Sdelphij } 184296341Sdelphij } 185238405Sjkim 186296341Sdelphij if (md_nid == -1) 187296341Sdelphij md = NULL; 188296341Sdelphij else { 189296341Sdelphij md = EVP_get_digestbynid(md_nid); 190296341Sdelphij if (!md) { 191296341Sdelphij EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_DIGEST); 192296341Sdelphij return 0; 193296341Sdelphij } 194296341Sdelphij } 195215697Ssimon 196296341Sdelphij if (!keygen(ctx, pass, passlen, param, cipher, md, en_de)) { 197296341Sdelphij EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_KEYGEN_FAILURE); 198296341Sdelphij return 0; 199296341Sdelphij } 200296341Sdelphij return 1; 201238405Sjkim} 202238405Sjkim 203238405SjkimDECLARE_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2); 204238405Sjkim 205238405Sjkimstatic int pbe2_cmp(const EVP_PBE_CTL *pbe1, const EVP_PBE_CTL *pbe2) 206296341Sdelphij{ 207296341Sdelphij int ret = pbe1->pbe_type - pbe2->pbe_type; 208296341Sdelphij if (ret) 209296341Sdelphij return ret; 210296341Sdelphij else 211296341Sdelphij return pbe1->pbe_nid - pbe2->pbe_nid; 212296341Sdelphij} 213238405Sjkim 214238405SjkimIMPLEMENT_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2); 215238405Sjkim 216296341Sdelphijstatic int pbe_cmp(const EVP_PBE_CTL *const *a, const EVP_PBE_CTL *const *b) 217296341Sdelphij{ 218296341Sdelphij int ret = (*a)->pbe_type - (*b)->pbe_type; 219296341Sdelphij if (ret) 220296341Sdelphij return ret; 221296341Sdelphij else 222296341Sdelphij return (*a)->pbe_nid - (*b)->pbe_nid; 223296341Sdelphij} 224238405Sjkim 225238405Sjkim/* Add a PBE algorithm */ 226238405Sjkim 227296341Sdelphijint EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, 228296341Sdelphij int md_nid, EVP_PBE_KEYGEN *keygen) 229296341Sdelphij{ 230296341Sdelphij EVP_PBE_CTL *pbe_tmp; 231296341Sdelphij if (!pbe_algs) 232296341Sdelphij pbe_algs = sk_EVP_PBE_CTL_new(pbe_cmp); 233296341Sdelphij if (!(pbe_tmp = (EVP_PBE_CTL *)OPENSSL_malloc(sizeof(EVP_PBE_CTL)))) { 234296341Sdelphij EVPerr(EVP_F_EVP_PBE_ALG_ADD_TYPE, ERR_R_MALLOC_FAILURE); 235296341Sdelphij return 0; 236296341Sdelphij } 237296341Sdelphij pbe_tmp->pbe_type = pbe_type; 238296341Sdelphij pbe_tmp->pbe_nid = pbe_nid; 239296341Sdelphij pbe_tmp->cipher_nid = cipher_nid; 240296341Sdelphij pbe_tmp->md_nid = md_nid; 241296341Sdelphij pbe_tmp->keygen = keygen; 242238405Sjkim 243296341Sdelphij sk_EVP_PBE_CTL_push(pbe_algs, pbe_tmp); 244296341Sdelphij return 1; 245296341Sdelphij} 246238405Sjkim 247238405Sjkimint EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, 248296341Sdelphij EVP_PBE_KEYGEN *keygen) 249296341Sdelphij{ 250296341Sdelphij int cipher_nid, md_nid; 251296341Sdelphij if (cipher) 252296341Sdelphij cipher_nid = EVP_CIPHER_nid(cipher); 253296341Sdelphij else 254296341Sdelphij cipher_nid = -1; 255296341Sdelphij if (md) 256296341Sdelphij md_nid = EVP_MD_type(md); 257296341Sdelphij else 258296341Sdelphij md_nid = -1; 259238405Sjkim 260296341Sdelphij return EVP_PBE_alg_add_type(EVP_PBE_TYPE_OUTER, nid, 261296341Sdelphij cipher_nid, md_nid, keygen); 262296341Sdelphij} 263238405Sjkim 264238405Sjkimint EVP_PBE_find(int type, int pbe_nid, 265296341Sdelphij int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen) 266296341Sdelphij{ 267296341Sdelphij EVP_PBE_CTL *pbetmp = NULL, pbelu; 268296341Sdelphij int i; 269296341Sdelphij if (pbe_nid == NID_undef) 270296341Sdelphij return 0; 271238405Sjkim 272296341Sdelphij pbelu.pbe_type = type; 273296341Sdelphij pbelu.pbe_nid = pbe_nid; 274238405Sjkim 275296341Sdelphij if (pbe_algs) { 276296341Sdelphij i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu); 277296341Sdelphij if (i != -1) 278296341Sdelphij pbetmp = sk_EVP_PBE_CTL_value(pbe_algs, i); 279296341Sdelphij } 280296341Sdelphij if (pbetmp == NULL) { 281296341Sdelphij pbetmp = OBJ_bsearch_pbe2(&pbelu, builtin_pbe, 282296341Sdelphij sizeof(builtin_pbe) / sizeof(EVP_PBE_CTL)); 283296341Sdelphij } 284296341Sdelphij if (pbetmp == NULL) 285296341Sdelphij return 0; 286296341Sdelphij if (pcnid) 287296341Sdelphij *pcnid = pbetmp->cipher_nid; 288296341Sdelphij if (pmnid) 289296341Sdelphij *pmnid = pbetmp->md_nid; 290296341Sdelphij if (pkeygen) 291296341Sdelphij *pkeygen = pbetmp->keygen; 292296341Sdelphij return 1; 293296341Sdelphij} 294238405Sjkim 295238405Sjkimstatic void free_evp_pbe_ctl(EVP_PBE_CTL *pbe) 296296341Sdelphij{ 297296341Sdelphij OPENSSL_freeFunc(pbe); 298296341Sdelphij} 299238405Sjkim 30055714Skrisvoid EVP_PBE_cleanup(void) 301296341Sdelphij{ 302296341Sdelphij sk_EVP_PBE_CTL_pop_free(pbe_algs, free_evp_pbe_ctl); 303296341Sdelphij pbe_algs = NULL; 304296341Sdelphij} 305