10Sstevel@tonic-gate /* crypto/evp/evp_key.c */ 20Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 30Sstevel@tonic-gate * All rights reserved. 40Sstevel@tonic-gate * 50Sstevel@tonic-gate * This package is an SSL implementation written 60Sstevel@tonic-gate * by Eric Young (eay@cryptsoft.com). 70Sstevel@tonic-gate * The implementation was written so as to conform with Netscapes SSL. 80Sstevel@tonic-gate * 90Sstevel@tonic-gate * This library is free for commercial and non-commercial use as long as 100Sstevel@tonic-gate * the following conditions are aheared to. The following conditions 110Sstevel@tonic-gate * apply to all code found in this distribution, be it the RC4, RSA, 120Sstevel@tonic-gate * lhash, DES, etc., code; not just the SSL code. The SSL documentation 130Sstevel@tonic-gate * included with this distribution is covered by the same copyright terms 140Sstevel@tonic-gate * except that the holder is Tim Hudson (tjh@cryptsoft.com). 150Sstevel@tonic-gate * 160Sstevel@tonic-gate * Copyright remains Eric Young's, and as such any Copyright notices in 170Sstevel@tonic-gate * the code are not to be removed. 180Sstevel@tonic-gate * If this package is used in a product, Eric Young should be given attribution 190Sstevel@tonic-gate * as the author of the parts of the library used. 200Sstevel@tonic-gate * This can be in the form of a textual message at program startup or 210Sstevel@tonic-gate * in documentation (online or textual) provided with the package. 220Sstevel@tonic-gate * 230Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 240Sstevel@tonic-gate * modification, are permitted provided that the following conditions 250Sstevel@tonic-gate * are met: 260Sstevel@tonic-gate * 1. Redistributions of source code must retain the copyright 270Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 280Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 290Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the 300Sstevel@tonic-gate * documentation and/or other materials provided with the distribution. 310Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software 320Sstevel@tonic-gate * must display the following acknowledgement: 330Sstevel@tonic-gate * "This product includes cryptographic software written by 340Sstevel@tonic-gate * Eric Young (eay@cryptsoft.com)" 350Sstevel@tonic-gate * The word 'cryptographic' can be left out if the rouines from the library 360Sstevel@tonic-gate * being used are not cryptographic related :-). 370Sstevel@tonic-gate * 4. If you include any Windows specific code (or a derivative thereof) from 380Sstevel@tonic-gate * the apps directory (application code) you must include an acknowledgement: 390Sstevel@tonic-gate * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 400Sstevel@tonic-gate * 410Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 420Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 430Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 440Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 450Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 460Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 470Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 480Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 490Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 500Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 510Sstevel@tonic-gate * SUCH DAMAGE. 520Sstevel@tonic-gate * 530Sstevel@tonic-gate * The licence and distribution terms for any publically available version or 540Sstevel@tonic-gate * derivative of this code cannot be changed. i.e. this code cannot simply be 550Sstevel@tonic-gate * copied and put under another distribution licence 560Sstevel@tonic-gate * [including the GNU Public Licence.] 570Sstevel@tonic-gate */ 580Sstevel@tonic-gate 59*2139Sjp161948 /* 60*2139Sjp161948 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 61*2139Sjp161948 * Use is subject to license terms. 62*2139Sjp161948 */ 63*2139Sjp161948 64*2139Sjp161948 #pragma ident "%Z%%M% %I% %E% SMI" 65*2139Sjp161948 660Sstevel@tonic-gate #include <stdio.h> 670Sstevel@tonic-gate #include "cryptlib.h" 680Sstevel@tonic-gate #include <openssl/x509.h> 690Sstevel@tonic-gate #include <openssl/objects.h> 700Sstevel@tonic-gate #include <openssl/evp.h> 710Sstevel@tonic-gate #include <openssl/ui.h> 720Sstevel@tonic-gate 730Sstevel@tonic-gate /* should be init to zeros. */ 740Sstevel@tonic-gate static char prompt_string[80]; 750Sstevel@tonic-gate 76*2139Sjp161948 void EVP_set_pw_prompt(const char *prompt) 770Sstevel@tonic-gate { 780Sstevel@tonic-gate if (prompt == NULL) 790Sstevel@tonic-gate prompt_string[0]='\0'; 800Sstevel@tonic-gate else 810Sstevel@tonic-gate { 820Sstevel@tonic-gate strncpy(prompt_string,prompt,79); 830Sstevel@tonic-gate prompt_string[79]='\0'; 840Sstevel@tonic-gate } 850Sstevel@tonic-gate } 860Sstevel@tonic-gate 870Sstevel@tonic-gate char *EVP_get_pw_prompt(void) 880Sstevel@tonic-gate { 890Sstevel@tonic-gate if (prompt_string[0] == '\0') 900Sstevel@tonic-gate return(NULL); 910Sstevel@tonic-gate else 920Sstevel@tonic-gate return(prompt_string); 930Sstevel@tonic-gate } 940Sstevel@tonic-gate 95*2139Sjp161948 #ifndef _BOOT 960Sstevel@tonic-gate /* For historical reasons, the standard function for reading passwords is 970Sstevel@tonic-gate * in the DES library -- if someone ever wants to disable DES, 980Sstevel@tonic-gate * this function will fail */ 990Sstevel@tonic-gate int EVP_read_pw_string(char *buf, int len, const char *prompt, int verify) 1000Sstevel@tonic-gate { 1010Sstevel@tonic-gate int ret; 1020Sstevel@tonic-gate char buff[BUFSIZ]; 1030Sstevel@tonic-gate UI *ui; 1040Sstevel@tonic-gate 1050Sstevel@tonic-gate if ((prompt == NULL) && (prompt_string[0] != '\0')) 1060Sstevel@tonic-gate prompt=prompt_string; 1070Sstevel@tonic-gate ui = UI_new(); 1080Sstevel@tonic-gate UI_add_input_string(ui,prompt,0,buf,0,(len>=BUFSIZ)?BUFSIZ-1:len); 1090Sstevel@tonic-gate if (verify) 1100Sstevel@tonic-gate UI_add_verify_string(ui,prompt,0, 1110Sstevel@tonic-gate buff,0,(len>=BUFSIZ)?BUFSIZ-1:len,buf); 1120Sstevel@tonic-gate ret = UI_process(ui); 1130Sstevel@tonic-gate UI_free(ui); 1140Sstevel@tonic-gate OPENSSL_cleanse(buff,BUFSIZ); 1150Sstevel@tonic-gate return ret; 1160Sstevel@tonic-gate } 1170Sstevel@tonic-gate #endif /* !_BOOT */ 1180Sstevel@tonic-gate 1190Sstevel@tonic-gate int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, 1200Sstevel@tonic-gate const unsigned char *salt, const unsigned char *data, int datal, 1210Sstevel@tonic-gate int count, unsigned char *key, unsigned char *iv) 1220Sstevel@tonic-gate { 1230Sstevel@tonic-gate EVP_MD_CTX c; 1240Sstevel@tonic-gate unsigned char md_buf[EVP_MAX_MD_SIZE]; 1250Sstevel@tonic-gate int niv,nkey,addmd=0; 1260Sstevel@tonic-gate unsigned int mds=0,i; 1270Sstevel@tonic-gate 1280Sstevel@tonic-gate nkey=type->key_len; 1290Sstevel@tonic-gate niv=type->iv_len; 1300Sstevel@tonic-gate OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH); 1310Sstevel@tonic-gate OPENSSL_assert(niv <= EVP_MAX_IV_LENGTH); 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate if (data == NULL) return(nkey); 1340Sstevel@tonic-gate 1350Sstevel@tonic-gate EVP_MD_CTX_init(&c); 1360Sstevel@tonic-gate for (;;) 1370Sstevel@tonic-gate { 1380Sstevel@tonic-gate EVP_DigestInit_ex(&c,md, NULL); 1390Sstevel@tonic-gate if (addmd++) 1400Sstevel@tonic-gate EVP_DigestUpdate(&c,&(md_buf[0]),mds); 1410Sstevel@tonic-gate EVP_DigestUpdate(&c,data,datal); 1420Sstevel@tonic-gate if (salt != NULL) 1430Sstevel@tonic-gate EVP_DigestUpdate(&c,salt,PKCS5_SALT_LEN); 1440Sstevel@tonic-gate EVP_DigestFinal_ex(&c,&(md_buf[0]),&mds); 1450Sstevel@tonic-gate 1460Sstevel@tonic-gate for (i=1; i<(unsigned int)count; i++) 1470Sstevel@tonic-gate { 1480Sstevel@tonic-gate EVP_DigestInit_ex(&c,md, NULL); 1490Sstevel@tonic-gate EVP_DigestUpdate(&c,&(md_buf[0]),mds); 1500Sstevel@tonic-gate EVP_DigestFinal_ex(&c,&(md_buf[0]),&mds); 1510Sstevel@tonic-gate } 1520Sstevel@tonic-gate i=0; 1530Sstevel@tonic-gate if (nkey) 1540Sstevel@tonic-gate { 1550Sstevel@tonic-gate for (;;) 1560Sstevel@tonic-gate { 1570Sstevel@tonic-gate if (nkey == 0) break; 1580Sstevel@tonic-gate if (i == mds) break; 1590Sstevel@tonic-gate if (key != NULL) 1600Sstevel@tonic-gate *(key++)=md_buf[i]; 1610Sstevel@tonic-gate nkey--; 1620Sstevel@tonic-gate i++; 1630Sstevel@tonic-gate } 1640Sstevel@tonic-gate } 1650Sstevel@tonic-gate if (niv && (i != mds)) 1660Sstevel@tonic-gate { 1670Sstevel@tonic-gate for (;;) 1680Sstevel@tonic-gate { 1690Sstevel@tonic-gate if (niv == 0) break; 1700Sstevel@tonic-gate if (i == mds) break; 1710Sstevel@tonic-gate if (iv != NULL) 1720Sstevel@tonic-gate *(iv++)=md_buf[i]; 1730Sstevel@tonic-gate niv--; 1740Sstevel@tonic-gate i++; 1750Sstevel@tonic-gate } 1760Sstevel@tonic-gate } 1770Sstevel@tonic-gate if ((nkey == 0) && (niv == 0)) break; 1780Sstevel@tonic-gate } 1790Sstevel@tonic-gate EVP_MD_CTX_cleanup(&c); 1800Sstevel@tonic-gate OPENSSL_cleanse(&(md_buf[0]),EVP_MAX_MD_SIZE); 1810Sstevel@tonic-gate return(type->key_len); 1820Sstevel@tonic-gate } 1830Sstevel@tonic-gate 184