xref: /onnv-gate/usr/src/common/openssl/ssl/s3_enc.c (revision 2139:6243c3338933)
10Sstevel@tonic-gate /* ssl/s3_enc.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 /* ====================================================================
590Sstevel@tonic-gate  * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
600Sstevel@tonic-gate  *
610Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
620Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
630Sstevel@tonic-gate  * are met:
640Sstevel@tonic-gate  *
650Sstevel@tonic-gate  * 1. Redistributions of source code must retain the above copyright
660Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
670Sstevel@tonic-gate  *
680Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
690Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in
700Sstevel@tonic-gate  *    the documentation and/or other materials provided with the
710Sstevel@tonic-gate  *    distribution.
720Sstevel@tonic-gate  *
730Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this
740Sstevel@tonic-gate  *    software must display the following acknowledgment:
750Sstevel@tonic-gate  *    "This product includes software developed by the OpenSSL Project
760Sstevel@tonic-gate  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
770Sstevel@tonic-gate  *
780Sstevel@tonic-gate  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
790Sstevel@tonic-gate  *    endorse or promote products derived from this software without
800Sstevel@tonic-gate  *    prior written permission. For written permission, please contact
810Sstevel@tonic-gate  *    openssl-core@openssl.org.
820Sstevel@tonic-gate  *
830Sstevel@tonic-gate  * 5. Products derived from this software may not be called "OpenSSL"
840Sstevel@tonic-gate  *    nor may "OpenSSL" appear in their names without prior written
850Sstevel@tonic-gate  *    permission of the OpenSSL Project.
860Sstevel@tonic-gate  *
870Sstevel@tonic-gate  * 6. Redistributions of any form whatsoever must retain the following
880Sstevel@tonic-gate  *    acknowledgment:
890Sstevel@tonic-gate  *    "This product includes software developed by the OpenSSL Project
900Sstevel@tonic-gate  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
910Sstevel@tonic-gate  *
920Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
930Sstevel@tonic-gate  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
940Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
950Sstevel@tonic-gate  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
960Sstevel@tonic-gate  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
970Sstevel@tonic-gate  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
980Sstevel@tonic-gate  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
990Sstevel@tonic-gate  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1000Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1010Sstevel@tonic-gate  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1020Sstevel@tonic-gate  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1030Sstevel@tonic-gate  * OF THE POSSIBILITY OF SUCH DAMAGE.
1040Sstevel@tonic-gate  * ====================================================================
1050Sstevel@tonic-gate  *
1060Sstevel@tonic-gate  * This product includes cryptographic software written by Eric Young
1070Sstevel@tonic-gate  * (eay@cryptsoft.com).  This product includes software written by Tim
1080Sstevel@tonic-gate  * Hudson (tjh@cryptsoft.com).
1090Sstevel@tonic-gate  *
1100Sstevel@tonic-gate  */
1110Sstevel@tonic-gate 
1120Sstevel@tonic-gate #include <stdio.h>
1130Sstevel@tonic-gate #include "ssl_locl.h"
1140Sstevel@tonic-gate #include <openssl/evp.h>
1150Sstevel@tonic-gate #include <openssl/md5.h>
1160Sstevel@tonic-gate 
1170Sstevel@tonic-gate static unsigned char ssl3_pad_1[48]={
1180Sstevel@tonic-gate 	0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
1190Sstevel@tonic-gate 	0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
1200Sstevel@tonic-gate 	0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
1210Sstevel@tonic-gate 	0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
1220Sstevel@tonic-gate 	0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
1230Sstevel@tonic-gate 	0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36 };
1240Sstevel@tonic-gate 
1250Sstevel@tonic-gate static unsigned char ssl3_pad_2[48]={
1260Sstevel@tonic-gate 	0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,
1270Sstevel@tonic-gate 	0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,
1280Sstevel@tonic-gate 	0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,
1290Sstevel@tonic-gate 	0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,
1300Sstevel@tonic-gate 	0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,
1310Sstevel@tonic-gate 	0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c };
1320Sstevel@tonic-gate 
1330Sstevel@tonic-gate static int ssl3_handshake_mac(SSL *s, EVP_MD_CTX *in_ctx,
1340Sstevel@tonic-gate 	const char *sender, int len, unsigned char *p);
1350Sstevel@tonic-gate 
ssl3_generate_key_block(SSL * s,unsigned char * km,int num)1360Sstevel@tonic-gate static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
1370Sstevel@tonic-gate 	{
1380Sstevel@tonic-gate 	EVP_MD_CTX m5;
1390Sstevel@tonic-gate 	EVP_MD_CTX s1;
1400Sstevel@tonic-gate 	unsigned char buf[16],smd[SHA_DIGEST_LENGTH];
1410Sstevel@tonic-gate 	unsigned char c='A';
142*2139Sjp161948 	unsigned int i,j,k;
1430Sstevel@tonic-gate 
1440Sstevel@tonic-gate #ifdef CHARSET_EBCDIC
1450Sstevel@tonic-gate 	c = os_toascii[c]; /*'A' in ASCII */
1460Sstevel@tonic-gate #endif
1470Sstevel@tonic-gate 	k=0;
1480Sstevel@tonic-gate 	EVP_MD_CTX_init(&m5);
1490Sstevel@tonic-gate 	EVP_MD_CTX_init(&s1);
150*2139Sjp161948 	for (i=0; (int)i<num; i+=MD5_DIGEST_LENGTH)
1510Sstevel@tonic-gate 		{
1520Sstevel@tonic-gate 		k++;
1530Sstevel@tonic-gate 		if (k > sizeof buf)
1540Sstevel@tonic-gate 			{
1550Sstevel@tonic-gate 			/* bug: 'buf' is too small for this ciphersuite */
1560Sstevel@tonic-gate 			SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR);
1570Sstevel@tonic-gate 			return 0;
1580Sstevel@tonic-gate 			}
1590Sstevel@tonic-gate 
1600Sstevel@tonic-gate 		for (j=0; j<k; j++)
1610Sstevel@tonic-gate 			buf[j]=c;
1620Sstevel@tonic-gate 		c++;
1630Sstevel@tonic-gate 		EVP_DigestInit_ex(&s1,EVP_sha1(), NULL);
1640Sstevel@tonic-gate 		EVP_DigestUpdate(&s1,buf,k);
1650Sstevel@tonic-gate 		EVP_DigestUpdate(&s1,s->session->master_key,
1660Sstevel@tonic-gate 			s->session->master_key_length);
1670Sstevel@tonic-gate 		EVP_DigestUpdate(&s1,s->s3->server_random,SSL3_RANDOM_SIZE);
1680Sstevel@tonic-gate 		EVP_DigestUpdate(&s1,s->s3->client_random,SSL3_RANDOM_SIZE);
1690Sstevel@tonic-gate 		EVP_DigestFinal_ex(&s1,smd,NULL);
1700Sstevel@tonic-gate 
1710Sstevel@tonic-gate 		EVP_DigestInit_ex(&m5,EVP_md5(), NULL);
1720Sstevel@tonic-gate 		EVP_DigestUpdate(&m5,s->session->master_key,
1730Sstevel@tonic-gate 			s->session->master_key_length);
1740Sstevel@tonic-gate 		EVP_DigestUpdate(&m5,smd,SHA_DIGEST_LENGTH);
175*2139Sjp161948 		if ((int)(i+MD5_DIGEST_LENGTH) > num)
1760Sstevel@tonic-gate 			{
1770Sstevel@tonic-gate 			EVP_DigestFinal_ex(&m5,smd,NULL);
1780Sstevel@tonic-gate 			memcpy(km,smd,(num-i));
1790Sstevel@tonic-gate 			}
1800Sstevel@tonic-gate 		else
1810Sstevel@tonic-gate 			EVP_DigestFinal_ex(&m5,km,NULL);
1820Sstevel@tonic-gate 
1830Sstevel@tonic-gate 		km+=MD5_DIGEST_LENGTH;
1840Sstevel@tonic-gate 		}
1850Sstevel@tonic-gate 	OPENSSL_cleanse(smd,SHA_DIGEST_LENGTH);
1860Sstevel@tonic-gate 	EVP_MD_CTX_cleanup(&m5);
1870Sstevel@tonic-gate 	EVP_MD_CTX_cleanup(&s1);
1880Sstevel@tonic-gate 	return 1;
1890Sstevel@tonic-gate 	}
1900Sstevel@tonic-gate 
ssl3_change_cipher_state(SSL * s,int which)1910Sstevel@tonic-gate int ssl3_change_cipher_state(SSL *s, int which)
1920Sstevel@tonic-gate 	{
1930Sstevel@tonic-gate 	unsigned char *p,*key_block,*mac_secret;
1940Sstevel@tonic-gate 	unsigned char exp_key[EVP_MAX_KEY_LENGTH];
1950Sstevel@tonic-gate 	unsigned char exp_iv[EVP_MAX_IV_LENGTH];
1960Sstevel@tonic-gate 	unsigned char *ms,*key,*iv,*er1,*er2;
1970Sstevel@tonic-gate 	EVP_CIPHER_CTX *dd;
1980Sstevel@tonic-gate 	const EVP_CIPHER *c;
199*2139Sjp161948 #ifndef OPENSSL_NO_COMP
2000Sstevel@tonic-gate 	COMP_METHOD *comp;
201*2139Sjp161948 #endif
2020Sstevel@tonic-gate 	const EVP_MD *m;
2030Sstevel@tonic-gate 	EVP_MD_CTX md;
2040Sstevel@tonic-gate 	int is_exp,n,i,j,k,cl;
2050Sstevel@tonic-gate 	int reuse_dd = 0;
2060Sstevel@tonic-gate 
2070Sstevel@tonic-gate 	is_exp=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
2080Sstevel@tonic-gate 	c=s->s3->tmp.new_sym_enc;
2090Sstevel@tonic-gate 	m=s->s3->tmp.new_hash;
210*2139Sjp161948 #ifndef OPENSSL_NO_COMP
2110Sstevel@tonic-gate 	if (s->s3->tmp.new_compression == NULL)
2120Sstevel@tonic-gate 		comp=NULL;
2130Sstevel@tonic-gate 	else
2140Sstevel@tonic-gate 		comp=s->s3->tmp.new_compression->method;
215*2139Sjp161948 #endif
2160Sstevel@tonic-gate 	key_block=s->s3->tmp.key_block;
2170Sstevel@tonic-gate 
2180Sstevel@tonic-gate 	if (which & SSL3_CC_READ)
2190Sstevel@tonic-gate 		{
2200Sstevel@tonic-gate 		if (s->enc_read_ctx != NULL)
2210Sstevel@tonic-gate 			reuse_dd = 1;
2220Sstevel@tonic-gate 		else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
2230Sstevel@tonic-gate 			goto err;
2240Sstevel@tonic-gate 		dd= s->enc_read_ctx;
2250Sstevel@tonic-gate 		s->read_hash=m;
226*2139Sjp161948 #ifndef OPENSSL_NO_COMP
2270Sstevel@tonic-gate 		/* COMPRESS */
2280Sstevel@tonic-gate 		if (s->expand != NULL)
2290Sstevel@tonic-gate 			{
2300Sstevel@tonic-gate 			COMP_CTX_free(s->expand);
2310Sstevel@tonic-gate 			s->expand=NULL;
2320Sstevel@tonic-gate 			}
2330Sstevel@tonic-gate 		if (comp != NULL)
2340Sstevel@tonic-gate 			{
2350Sstevel@tonic-gate 			s->expand=COMP_CTX_new(comp);
2360Sstevel@tonic-gate 			if (s->expand == NULL)
2370Sstevel@tonic-gate 				{
2380Sstevel@tonic-gate 				SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
2390Sstevel@tonic-gate 				goto err2;
2400Sstevel@tonic-gate 				}
2410Sstevel@tonic-gate 			if (s->s3->rrec.comp == NULL)
2420Sstevel@tonic-gate 				s->s3->rrec.comp=(unsigned char *)
2430Sstevel@tonic-gate 					OPENSSL_malloc(SSL3_RT_MAX_PLAIN_LENGTH);
2440Sstevel@tonic-gate 			if (s->s3->rrec.comp == NULL)
2450Sstevel@tonic-gate 				goto err;
2460Sstevel@tonic-gate 			}
247*2139Sjp161948 #endif
2480Sstevel@tonic-gate 		memset(&(s->s3->read_sequence[0]),0,8);
2490Sstevel@tonic-gate 		mac_secret= &(s->s3->read_mac_secret[0]);
2500Sstevel@tonic-gate 		}
2510Sstevel@tonic-gate 	else
2520Sstevel@tonic-gate 		{
2530Sstevel@tonic-gate 		if (s->enc_write_ctx != NULL)
2540Sstevel@tonic-gate 			reuse_dd = 1;
2550Sstevel@tonic-gate 		else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
2560Sstevel@tonic-gate 			goto err;
2570Sstevel@tonic-gate 		dd= s->enc_write_ctx;
2580Sstevel@tonic-gate 		s->write_hash=m;
259*2139Sjp161948 #ifndef OPENSSL_NO_COMP
2600Sstevel@tonic-gate 		/* COMPRESS */
2610Sstevel@tonic-gate 		if (s->compress != NULL)
2620Sstevel@tonic-gate 			{
2630Sstevel@tonic-gate 			COMP_CTX_free(s->compress);
2640Sstevel@tonic-gate 			s->compress=NULL;
2650Sstevel@tonic-gate 			}
2660Sstevel@tonic-gate 		if (comp != NULL)
2670Sstevel@tonic-gate 			{
2680Sstevel@tonic-gate 			s->compress=COMP_CTX_new(comp);
2690Sstevel@tonic-gate 			if (s->compress == NULL)
2700Sstevel@tonic-gate 				{
2710Sstevel@tonic-gate 				SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
2720Sstevel@tonic-gate 				goto err2;
2730Sstevel@tonic-gate 				}
2740Sstevel@tonic-gate 			}
275*2139Sjp161948 #endif
2760Sstevel@tonic-gate 		memset(&(s->s3->write_sequence[0]),0,8);
2770Sstevel@tonic-gate 		mac_secret= &(s->s3->write_mac_secret[0]);
2780Sstevel@tonic-gate 		}
2790Sstevel@tonic-gate 
2800Sstevel@tonic-gate 	if (reuse_dd)
2810Sstevel@tonic-gate 		EVP_CIPHER_CTX_cleanup(dd);
2820Sstevel@tonic-gate 	EVP_CIPHER_CTX_init(dd);
2830Sstevel@tonic-gate 
2840Sstevel@tonic-gate 	p=s->s3->tmp.key_block;
2850Sstevel@tonic-gate 	i=EVP_MD_size(m);
2860Sstevel@tonic-gate 	cl=EVP_CIPHER_key_length(c);
2870Sstevel@tonic-gate 	j=is_exp ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ?
288*2139Sjp161948 		 cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl;
2890Sstevel@tonic-gate 	/* Was j=(is_exp)?5:EVP_CIPHER_key_length(c); */
2900Sstevel@tonic-gate 	k=EVP_CIPHER_iv_length(c);
2910Sstevel@tonic-gate 	if (	(which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
2920Sstevel@tonic-gate 		(which == SSL3_CHANGE_CIPHER_SERVER_READ))
2930Sstevel@tonic-gate 		{
2940Sstevel@tonic-gate 		ms=  &(p[ 0]); n=i+i;
2950Sstevel@tonic-gate 		key= &(p[ n]); n+=j+j;
2960Sstevel@tonic-gate 		iv=  &(p[ n]); n+=k+k;
2970Sstevel@tonic-gate 		er1= &(s->s3->client_random[0]);
2980Sstevel@tonic-gate 		er2= &(s->s3->server_random[0]);
2990Sstevel@tonic-gate 		}
3000Sstevel@tonic-gate 	else
3010Sstevel@tonic-gate 		{
3020Sstevel@tonic-gate 		n=i;
3030Sstevel@tonic-gate 		ms=  &(p[ n]); n+=i+j;
3040Sstevel@tonic-gate 		key= &(p[ n]); n+=j+k;
3050Sstevel@tonic-gate 		iv=  &(p[ n]); n+=k;
3060Sstevel@tonic-gate 		er1= &(s->s3->server_random[0]);
3070Sstevel@tonic-gate 		er2= &(s->s3->client_random[0]);
3080Sstevel@tonic-gate 		}
3090Sstevel@tonic-gate 
3100Sstevel@tonic-gate 	if (n > s->s3->tmp.key_block_length)
3110Sstevel@tonic-gate 		{
3120Sstevel@tonic-gate 		SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR);
3130Sstevel@tonic-gate 		goto err2;
3140Sstevel@tonic-gate 		}
3150Sstevel@tonic-gate 
3160Sstevel@tonic-gate 	EVP_MD_CTX_init(&md);
3170Sstevel@tonic-gate 	memcpy(mac_secret,ms,i);
3180Sstevel@tonic-gate 	if (is_exp)
3190Sstevel@tonic-gate 		{
3200Sstevel@tonic-gate 		/* In here I set both the read and write key/iv to the
3210Sstevel@tonic-gate 		 * same value since only the correct one will be used :-).
3220Sstevel@tonic-gate 		 */
3230Sstevel@tonic-gate 		EVP_DigestInit_ex(&md,EVP_md5(), NULL);
3240Sstevel@tonic-gate 		EVP_DigestUpdate(&md,key,j);
3250Sstevel@tonic-gate 		EVP_DigestUpdate(&md,er1,SSL3_RANDOM_SIZE);
3260Sstevel@tonic-gate 		EVP_DigestUpdate(&md,er2,SSL3_RANDOM_SIZE);
3270Sstevel@tonic-gate 		EVP_DigestFinal_ex(&md,&(exp_key[0]),NULL);
3280Sstevel@tonic-gate 		key= &(exp_key[0]);
3290Sstevel@tonic-gate 
3300Sstevel@tonic-gate 		if (k > 0)
3310Sstevel@tonic-gate 			{
3320Sstevel@tonic-gate 			EVP_DigestInit_ex(&md,EVP_md5(), NULL);
3330Sstevel@tonic-gate 			EVP_DigestUpdate(&md,er1,SSL3_RANDOM_SIZE);
3340Sstevel@tonic-gate 			EVP_DigestUpdate(&md,er2,SSL3_RANDOM_SIZE);
3350Sstevel@tonic-gate 			EVP_DigestFinal_ex(&md,&(exp_iv[0]),NULL);
3360Sstevel@tonic-gate 			iv= &(exp_iv[0]);
3370Sstevel@tonic-gate 			}
3380Sstevel@tonic-gate 		}
3390Sstevel@tonic-gate 
3400Sstevel@tonic-gate 	s->session->key_arg_length=0;
3410Sstevel@tonic-gate 
3420Sstevel@tonic-gate 	EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE));
3430Sstevel@tonic-gate 
3440Sstevel@tonic-gate 	OPENSSL_cleanse(&(exp_key[0]),sizeof(exp_key));
3450Sstevel@tonic-gate 	OPENSSL_cleanse(&(exp_iv[0]),sizeof(exp_iv));
3460Sstevel@tonic-gate 	EVP_MD_CTX_cleanup(&md);
3470Sstevel@tonic-gate 	return(1);
3480Sstevel@tonic-gate err:
3490Sstevel@tonic-gate 	SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE);
3500Sstevel@tonic-gate err2:
3510Sstevel@tonic-gate 	return(0);
3520Sstevel@tonic-gate 	}
3530Sstevel@tonic-gate 
ssl3_setup_key_block(SSL * s)3540Sstevel@tonic-gate int ssl3_setup_key_block(SSL *s)
3550Sstevel@tonic-gate 	{
3560Sstevel@tonic-gate 	unsigned char *p;
3570Sstevel@tonic-gate 	const EVP_CIPHER *c;
3580Sstevel@tonic-gate 	const EVP_MD *hash;
3590Sstevel@tonic-gate 	int num;
3600Sstevel@tonic-gate 	int ret = 0;
3610Sstevel@tonic-gate 	SSL_COMP *comp;
3620Sstevel@tonic-gate 
3630Sstevel@tonic-gate 	if (s->s3->tmp.key_block_length != 0)
3640Sstevel@tonic-gate 		return(1);
3650Sstevel@tonic-gate 
3660Sstevel@tonic-gate 	if (!ssl_cipher_get_evp(s->session,&c,&hash,&comp))
3670Sstevel@tonic-gate 		{
3680Sstevel@tonic-gate 		SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
3690Sstevel@tonic-gate 		return(0);
3700Sstevel@tonic-gate 		}
3710Sstevel@tonic-gate 
3720Sstevel@tonic-gate 	s->s3->tmp.new_sym_enc=c;
3730Sstevel@tonic-gate 	s->s3->tmp.new_hash=hash;
374*2139Sjp161948 #ifdef OPENSSL_NO_COMP
375*2139Sjp161948 	s->s3->tmp.new_compression=NULL;
376*2139Sjp161948 #else
3770Sstevel@tonic-gate 	s->s3->tmp.new_compression=comp;
378*2139Sjp161948 #endif
3790Sstevel@tonic-gate 
3800Sstevel@tonic-gate 	num=EVP_CIPHER_key_length(c)+EVP_MD_size(hash)+EVP_CIPHER_iv_length(c);
3810Sstevel@tonic-gate 	num*=2;
3820Sstevel@tonic-gate 
3830Sstevel@tonic-gate 	ssl3_cleanup_key_block(s);
3840Sstevel@tonic-gate 
3850Sstevel@tonic-gate 	if ((p=OPENSSL_malloc(num)) == NULL)
3860Sstevel@tonic-gate 		goto err;
3870Sstevel@tonic-gate 
3880Sstevel@tonic-gate 	s->s3->tmp.key_block_length=num;
3890Sstevel@tonic-gate 	s->s3->tmp.key_block=p;
3900Sstevel@tonic-gate 
3910Sstevel@tonic-gate 	ret = ssl3_generate_key_block(s,p,num);
3920Sstevel@tonic-gate 
3930Sstevel@tonic-gate 	if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
3940Sstevel@tonic-gate 		{
3950Sstevel@tonic-gate 		/* enable vulnerability countermeasure for CBC ciphers with
3960Sstevel@tonic-gate 		 * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt)
3970Sstevel@tonic-gate 		 */
3980Sstevel@tonic-gate 		s->s3->need_empty_fragments = 1;
3990Sstevel@tonic-gate 
4000Sstevel@tonic-gate 		if (s->session->cipher != NULL)
4010Sstevel@tonic-gate 			{
4020Sstevel@tonic-gate 			if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_eNULL)
4030Sstevel@tonic-gate 				s->s3->need_empty_fragments = 0;
4040Sstevel@tonic-gate 
4050Sstevel@tonic-gate #ifndef OPENSSL_NO_RC4
4060Sstevel@tonic-gate 			if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_RC4)
4070Sstevel@tonic-gate 				s->s3->need_empty_fragments = 0;
4080Sstevel@tonic-gate #endif
4090Sstevel@tonic-gate 			}
4100Sstevel@tonic-gate 		}
4110Sstevel@tonic-gate 
4120Sstevel@tonic-gate 	return ret;
4130Sstevel@tonic-gate 
4140Sstevel@tonic-gate err:
4150Sstevel@tonic-gate 	SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE);
4160Sstevel@tonic-gate 	return(0);
4170Sstevel@tonic-gate 	}
4180Sstevel@tonic-gate 
ssl3_cleanup_key_block(SSL * s)4190Sstevel@tonic-gate void ssl3_cleanup_key_block(SSL *s)
4200Sstevel@tonic-gate 	{
4210Sstevel@tonic-gate 	if (s->s3->tmp.key_block != NULL)
4220Sstevel@tonic-gate 		{
4230Sstevel@tonic-gate 		OPENSSL_cleanse(s->s3->tmp.key_block,
4240Sstevel@tonic-gate 			s->s3->tmp.key_block_length);
4250Sstevel@tonic-gate 		OPENSSL_free(s->s3->tmp.key_block);
4260Sstevel@tonic-gate 		s->s3->tmp.key_block=NULL;
4270Sstevel@tonic-gate 		}
4280Sstevel@tonic-gate 	s->s3->tmp.key_block_length=0;
4290Sstevel@tonic-gate 	}
4300Sstevel@tonic-gate 
ssl3_enc(SSL * s,int send)4310Sstevel@tonic-gate int ssl3_enc(SSL *s, int send)
4320Sstevel@tonic-gate 	{
4330Sstevel@tonic-gate 	SSL3_RECORD *rec;
4340Sstevel@tonic-gate 	EVP_CIPHER_CTX *ds;
4350Sstevel@tonic-gate 	unsigned long l;
4360Sstevel@tonic-gate 	int bs,i;
4370Sstevel@tonic-gate 	const EVP_CIPHER *enc;
4380Sstevel@tonic-gate 
4390Sstevel@tonic-gate 	if (send)
4400Sstevel@tonic-gate 		{
4410Sstevel@tonic-gate 		ds=s->enc_write_ctx;
4420Sstevel@tonic-gate 		rec= &(s->s3->wrec);
4430Sstevel@tonic-gate 		if (s->enc_write_ctx == NULL)
4440Sstevel@tonic-gate 			enc=NULL;
4450Sstevel@tonic-gate 		else
4460Sstevel@tonic-gate 			enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
4470Sstevel@tonic-gate 		}
4480Sstevel@tonic-gate 	else
4490Sstevel@tonic-gate 		{
4500Sstevel@tonic-gate 		ds=s->enc_read_ctx;
4510Sstevel@tonic-gate 		rec= &(s->s3->rrec);
4520Sstevel@tonic-gate 		if (s->enc_read_ctx == NULL)
4530Sstevel@tonic-gate 			enc=NULL;
4540Sstevel@tonic-gate 		else
4550Sstevel@tonic-gate 			enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
4560Sstevel@tonic-gate 		}
4570Sstevel@tonic-gate 
4580Sstevel@tonic-gate 	if ((s->session == NULL) || (ds == NULL) ||
4590Sstevel@tonic-gate 		(enc == NULL))
4600Sstevel@tonic-gate 		{
4610Sstevel@tonic-gate 		memmove(rec->data,rec->input,rec->length);
4620Sstevel@tonic-gate 		rec->input=rec->data;
4630Sstevel@tonic-gate 		}
4640Sstevel@tonic-gate 	else
4650Sstevel@tonic-gate 		{
4660Sstevel@tonic-gate 		l=rec->length;
4670Sstevel@tonic-gate 		bs=EVP_CIPHER_block_size(ds->cipher);
4680Sstevel@tonic-gate 
4690Sstevel@tonic-gate 		/* COMPRESS */
4700Sstevel@tonic-gate 
4710Sstevel@tonic-gate 		if ((bs != 1) && send)
4720Sstevel@tonic-gate 			{
4730Sstevel@tonic-gate 			i=bs-((int)l%bs);
4740Sstevel@tonic-gate 
4750Sstevel@tonic-gate 			/* we need to add 'i-1' padding bytes */
4760Sstevel@tonic-gate 			l+=i;
4770Sstevel@tonic-gate 			rec->length+=i;
4780Sstevel@tonic-gate 			rec->input[l-1]=(i-1);
4790Sstevel@tonic-gate 			}
4800Sstevel@tonic-gate 
4810Sstevel@tonic-gate 		if (!send)
4820Sstevel@tonic-gate 			{
4830Sstevel@tonic-gate 			if (l == 0 || l%bs != 0)
4840Sstevel@tonic-gate 				{
4850Sstevel@tonic-gate 				SSLerr(SSL_F_SSL3_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
4860Sstevel@tonic-gate 				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED);
4870Sstevel@tonic-gate 				return 0;
4880Sstevel@tonic-gate 				}
4890Sstevel@tonic-gate 			/* otherwise, rec->length >= bs */
4900Sstevel@tonic-gate 			}
4910Sstevel@tonic-gate 
4920Sstevel@tonic-gate 		EVP_Cipher(ds,rec->data,rec->input,l);
4930Sstevel@tonic-gate 
4940Sstevel@tonic-gate 		if ((bs != 1) && !send)
4950Sstevel@tonic-gate 			{
4960Sstevel@tonic-gate 			i=rec->data[l-1]+1;
4970Sstevel@tonic-gate 			/* SSL 3.0 bounds the number of padding bytes by the block size;
4980Sstevel@tonic-gate 			 * padding bytes (except the last one) are arbitrary */
4990Sstevel@tonic-gate 			if (i > bs)
5000Sstevel@tonic-gate 				{
5010Sstevel@tonic-gate 				/* Incorrect padding. SSLerr() and ssl3_alert are done
5020Sstevel@tonic-gate 				 * by caller: we don't want to reveal whether this is
5030Sstevel@tonic-gate 				 * a decryption error or a MAC verification failure
5040Sstevel@tonic-gate 				 * (see http://www.openssl.org/~bodo/tls-cbc.txt) */
5050Sstevel@tonic-gate 				return -1;
5060Sstevel@tonic-gate 				}
5070Sstevel@tonic-gate 			/* now i <= bs <= rec->length */
5080Sstevel@tonic-gate 			rec->length-=i;
5090Sstevel@tonic-gate 			}
5100Sstevel@tonic-gate 		}
5110Sstevel@tonic-gate 	return(1);
5120Sstevel@tonic-gate 	}
5130Sstevel@tonic-gate 
ssl3_init_finished_mac(SSL * s)5140Sstevel@tonic-gate void ssl3_init_finished_mac(SSL *s)
5150Sstevel@tonic-gate 	{
5160Sstevel@tonic-gate 	EVP_DigestInit_ex(&(s->s3->finish_dgst1),s->ctx->md5, NULL);
5170Sstevel@tonic-gate 	EVP_DigestInit_ex(&(s->s3->finish_dgst2),s->ctx->sha1, NULL);
5180Sstevel@tonic-gate 	}
5190Sstevel@tonic-gate 
ssl3_finish_mac(SSL * s,const unsigned char * buf,int len)5200Sstevel@tonic-gate void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len)
5210Sstevel@tonic-gate 	{
5220Sstevel@tonic-gate 	EVP_DigestUpdate(&(s->s3->finish_dgst1),buf,len);
5230Sstevel@tonic-gate 	EVP_DigestUpdate(&(s->s3->finish_dgst2),buf,len);
5240Sstevel@tonic-gate 	}
5250Sstevel@tonic-gate 
ssl3_cert_verify_mac(SSL * s,EVP_MD_CTX * ctx,unsigned char * p)5260Sstevel@tonic-gate int ssl3_cert_verify_mac(SSL *s, EVP_MD_CTX *ctx, unsigned char *p)
5270Sstevel@tonic-gate 	{
5280Sstevel@tonic-gate 	return(ssl3_handshake_mac(s,ctx,NULL,0,p));
5290Sstevel@tonic-gate 	}
5300Sstevel@tonic-gate 
ssl3_final_finish_mac(SSL * s,EVP_MD_CTX * ctx1,EVP_MD_CTX * ctx2,const char * sender,int len,unsigned char * p)5310Sstevel@tonic-gate int ssl3_final_finish_mac(SSL *s, EVP_MD_CTX *ctx1, EVP_MD_CTX *ctx2,
5320Sstevel@tonic-gate 	     const char *sender, int len, unsigned char *p)
5330Sstevel@tonic-gate 	{
5340Sstevel@tonic-gate 	int ret;
5350Sstevel@tonic-gate 
5360Sstevel@tonic-gate 	ret=ssl3_handshake_mac(s,ctx1,sender,len,p);
5370Sstevel@tonic-gate 	p+=ret;
5380Sstevel@tonic-gate 	ret+=ssl3_handshake_mac(s,ctx2,sender,len,p);
5390Sstevel@tonic-gate 	return(ret);
5400Sstevel@tonic-gate 	}
5410Sstevel@tonic-gate 
ssl3_handshake_mac(SSL * s,EVP_MD_CTX * in_ctx,const char * sender,int len,unsigned char * p)5420Sstevel@tonic-gate static int ssl3_handshake_mac(SSL *s, EVP_MD_CTX *in_ctx,
5430Sstevel@tonic-gate 	     const char *sender, int len, unsigned char *p)
5440Sstevel@tonic-gate 	{
5450Sstevel@tonic-gate 	unsigned int ret;
5460Sstevel@tonic-gate 	int npad,n;
5470Sstevel@tonic-gate 	unsigned int i;
5480Sstevel@tonic-gate 	unsigned char md_buf[EVP_MAX_MD_SIZE];
5490Sstevel@tonic-gate 	EVP_MD_CTX ctx;
5500Sstevel@tonic-gate 
5510Sstevel@tonic-gate 	EVP_MD_CTX_init(&ctx);
5520Sstevel@tonic-gate 	EVP_MD_CTX_copy_ex(&ctx,in_ctx);
5530Sstevel@tonic-gate 
5540Sstevel@tonic-gate 	n=EVP_MD_CTX_size(&ctx);
5550Sstevel@tonic-gate 	npad=(48/n)*n;
5560Sstevel@tonic-gate 
5570Sstevel@tonic-gate 	if (sender != NULL)
5580Sstevel@tonic-gate 		EVP_DigestUpdate(&ctx,sender,len);
5590Sstevel@tonic-gate 	EVP_DigestUpdate(&ctx,s->session->master_key,
5600Sstevel@tonic-gate 		s->session->master_key_length);
5610Sstevel@tonic-gate 	EVP_DigestUpdate(&ctx,ssl3_pad_1,npad);
5620Sstevel@tonic-gate 	EVP_DigestFinal_ex(&ctx,md_buf,&i);
5630Sstevel@tonic-gate 
5640Sstevel@tonic-gate 	EVP_DigestInit_ex(&ctx,EVP_MD_CTX_md(&ctx), NULL);
5650Sstevel@tonic-gate 	EVP_DigestUpdate(&ctx,s->session->master_key,
5660Sstevel@tonic-gate 		s->session->master_key_length);
5670Sstevel@tonic-gate 	EVP_DigestUpdate(&ctx,ssl3_pad_2,npad);
5680Sstevel@tonic-gate 	EVP_DigestUpdate(&ctx,md_buf,i);
5690Sstevel@tonic-gate 	EVP_DigestFinal_ex(&ctx,p,&ret);
5700Sstevel@tonic-gate 
5710Sstevel@tonic-gate 	EVP_MD_CTX_cleanup(&ctx);
5720Sstevel@tonic-gate 
5730Sstevel@tonic-gate 	return((int)ret);
5740Sstevel@tonic-gate 	}
5750Sstevel@tonic-gate 
ssl3_mac(SSL * ssl,unsigned char * md,int send)5760Sstevel@tonic-gate int ssl3_mac(SSL *ssl, unsigned char *md, int send)
5770Sstevel@tonic-gate 	{
5780Sstevel@tonic-gate 	SSL3_RECORD *rec;
5790Sstevel@tonic-gate 	unsigned char *mac_sec,*seq;
5800Sstevel@tonic-gate 	EVP_MD_CTX md_ctx;
5810Sstevel@tonic-gate 	const EVP_MD *hash;
5820Sstevel@tonic-gate 	unsigned char *p,rec_char;
5830Sstevel@tonic-gate 	unsigned int md_size;
584*2139Sjp161948 	int npad;
5850Sstevel@tonic-gate 
5860Sstevel@tonic-gate 	if (send)
5870Sstevel@tonic-gate 		{
5880Sstevel@tonic-gate 		rec= &(ssl->s3->wrec);
5890Sstevel@tonic-gate 		mac_sec= &(ssl->s3->write_mac_secret[0]);
5900Sstevel@tonic-gate 		seq= &(ssl->s3->write_sequence[0]);
5910Sstevel@tonic-gate 		hash=ssl->write_hash;
5920Sstevel@tonic-gate 		}
5930Sstevel@tonic-gate 	else
5940Sstevel@tonic-gate 		{
5950Sstevel@tonic-gate 		rec= &(ssl->s3->rrec);
5960Sstevel@tonic-gate 		mac_sec= &(ssl->s3->read_mac_secret[0]);
5970Sstevel@tonic-gate 		seq= &(ssl->s3->read_sequence[0]);
5980Sstevel@tonic-gate 		hash=ssl->read_hash;
5990Sstevel@tonic-gate 		}
6000Sstevel@tonic-gate 
6010Sstevel@tonic-gate 	md_size=EVP_MD_size(hash);
6020Sstevel@tonic-gate 	npad=(48/md_size)*md_size;
6030Sstevel@tonic-gate 
6040Sstevel@tonic-gate 	/* Chop the digest off the end :-) */
6050Sstevel@tonic-gate 	EVP_MD_CTX_init(&md_ctx);
6060Sstevel@tonic-gate 
6070Sstevel@tonic-gate 	EVP_DigestInit_ex(  &md_ctx,hash, NULL);
6080Sstevel@tonic-gate 	EVP_DigestUpdate(&md_ctx,mac_sec,md_size);
6090Sstevel@tonic-gate 	EVP_DigestUpdate(&md_ctx,ssl3_pad_1,npad);
6100Sstevel@tonic-gate 	EVP_DigestUpdate(&md_ctx,seq,8);
6110Sstevel@tonic-gate 	rec_char=rec->type;
6120Sstevel@tonic-gate 	EVP_DigestUpdate(&md_ctx,&rec_char,1);
6130Sstevel@tonic-gate 	p=md;
6140Sstevel@tonic-gate 	s2n(rec->length,p);
6150Sstevel@tonic-gate 	EVP_DigestUpdate(&md_ctx,md,2);
6160Sstevel@tonic-gate 	EVP_DigestUpdate(&md_ctx,rec->input,rec->length);
6170Sstevel@tonic-gate 	EVP_DigestFinal_ex( &md_ctx,md,NULL);
6180Sstevel@tonic-gate 
6190Sstevel@tonic-gate 	EVP_DigestInit_ex(  &md_ctx,hash, NULL);
6200Sstevel@tonic-gate 	EVP_DigestUpdate(&md_ctx,mac_sec,md_size);
6210Sstevel@tonic-gate 	EVP_DigestUpdate(&md_ctx,ssl3_pad_2,npad);
6220Sstevel@tonic-gate 	EVP_DigestUpdate(&md_ctx,md,md_size);
6230Sstevel@tonic-gate 	EVP_DigestFinal_ex( &md_ctx,md,&md_size);
6240Sstevel@tonic-gate 
6250Sstevel@tonic-gate 	EVP_MD_CTX_cleanup(&md_ctx);
6260Sstevel@tonic-gate 
627*2139Sjp161948 	ssl3_record_sequence_update(seq);
628*2139Sjp161948 	return(md_size);
629*2139Sjp161948 	}
630*2139Sjp161948 
ssl3_record_sequence_update(unsigned char * seq)631*2139Sjp161948 void ssl3_record_sequence_update(unsigned char *seq)
632*2139Sjp161948 	{
633*2139Sjp161948 	int i;
634*2139Sjp161948 
6350Sstevel@tonic-gate 	for (i=7; i>=0; i--)
6360Sstevel@tonic-gate 		{
6370Sstevel@tonic-gate 		++seq[i];
6380Sstevel@tonic-gate 		if (seq[i] != 0) break;
6390Sstevel@tonic-gate 		}
6400Sstevel@tonic-gate 	}
6410Sstevel@tonic-gate 
ssl3_generate_master_secret(SSL * s,unsigned char * out,unsigned char * p,int len)6420Sstevel@tonic-gate int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
6430Sstevel@tonic-gate 	     int len)
6440Sstevel@tonic-gate 	{
6450Sstevel@tonic-gate 	static const unsigned char *salt[3]={
6460Sstevel@tonic-gate #ifndef CHARSET_EBCDIC
6470Sstevel@tonic-gate 		(const unsigned char *)"A",
6480Sstevel@tonic-gate 		(const unsigned char *)"BB",
6490Sstevel@tonic-gate 		(const unsigned char *)"CCC",
6500Sstevel@tonic-gate #else
6510Sstevel@tonic-gate 		(const unsigned char *)"\x41",
6520Sstevel@tonic-gate 		(const unsigned char *)"\x42\x42",
6530Sstevel@tonic-gate 		(const unsigned char *)"\x43\x43\x43",
6540Sstevel@tonic-gate #endif
6550Sstevel@tonic-gate 		};
6560Sstevel@tonic-gate 	unsigned char buf[EVP_MAX_MD_SIZE];
6570Sstevel@tonic-gate 	EVP_MD_CTX ctx;
6580Sstevel@tonic-gate 	int i,ret=0;
6590Sstevel@tonic-gate 	unsigned int n;
6600Sstevel@tonic-gate 
6610Sstevel@tonic-gate 	EVP_MD_CTX_init(&ctx);
6620Sstevel@tonic-gate 	for (i=0; i<3; i++)
6630Sstevel@tonic-gate 		{
6640Sstevel@tonic-gate 		EVP_DigestInit_ex(&ctx,s->ctx->sha1, NULL);
6650Sstevel@tonic-gate 		EVP_DigestUpdate(&ctx,salt[i],strlen((const char *)salt[i]));
6660Sstevel@tonic-gate 		EVP_DigestUpdate(&ctx,p,len);
6670Sstevel@tonic-gate 		EVP_DigestUpdate(&ctx,&(s->s3->client_random[0]),
6680Sstevel@tonic-gate 			SSL3_RANDOM_SIZE);
6690Sstevel@tonic-gate 		EVP_DigestUpdate(&ctx,&(s->s3->server_random[0]),
6700Sstevel@tonic-gate 			SSL3_RANDOM_SIZE);
6710Sstevel@tonic-gate 		EVP_DigestFinal_ex(&ctx,buf,&n);
6720Sstevel@tonic-gate 
6730Sstevel@tonic-gate 		EVP_DigestInit_ex(&ctx,s->ctx->md5, NULL);
6740Sstevel@tonic-gate 		EVP_DigestUpdate(&ctx,p,len);
6750Sstevel@tonic-gate 		EVP_DigestUpdate(&ctx,buf,n);
6760Sstevel@tonic-gate 		EVP_DigestFinal_ex(&ctx,out,&n);
6770Sstevel@tonic-gate 		out+=n;
6780Sstevel@tonic-gate 		ret+=n;
6790Sstevel@tonic-gate 		}
6800Sstevel@tonic-gate 	EVP_MD_CTX_cleanup(&ctx);
6810Sstevel@tonic-gate 	return(ret);
6820Sstevel@tonic-gate 	}
6830Sstevel@tonic-gate 
ssl3_alert_code(int code)6840Sstevel@tonic-gate int ssl3_alert_code(int code)
6850Sstevel@tonic-gate 	{
6860Sstevel@tonic-gate 	switch (code)
6870Sstevel@tonic-gate 		{
6880Sstevel@tonic-gate 	case SSL_AD_CLOSE_NOTIFY:	return(SSL3_AD_CLOSE_NOTIFY);
6890Sstevel@tonic-gate 	case SSL_AD_UNEXPECTED_MESSAGE:	return(SSL3_AD_UNEXPECTED_MESSAGE);
6900Sstevel@tonic-gate 	case SSL_AD_BAD_RECORD_MAC:	return(SSL3_AD_BAD_RECORD_MAC);
6910Sstevel@tonic-gate 	case SSL_AD_DECRYPTION_FAILED:	return(SSL3_AD_BAD_RECORD_MAC);
6920Sstevel@tonic-gate 	case SSL_AD_RECORD_OVERFLOW:	return(SSL3_AD_BAD_RECORD_MAC);
6930Sstevel@tonic-gate 	case SSL_AD_DECOMPRESSION_FAILURE:return(SSL3_AD_DECOMPRESSION_FAILURE);
6940Sstevel@tonic-gate 	case SSL_AD_HANDSHAKE_FAILURE:	return(SSL3_AD_HANDSHAKE_FAILURE);
6950Sstevel@tonic-gate 	case SSL_AD_NO_CERTIFICATE:	return(SSL3_AD_NO_CERTIFICATE);
6960Sstevel@tonic-gate 	case SSL_AD_BAD_CERTIFICATE:	return(SSL3_AD_BAD_CERTIFICATE);
6970Sstevel@tonic-gate 	case SSL_AD_UNSUPPORTED_CERTIFICATE:return(SSL3_AD_UNSUPPORTED_CERTIFICATE);
6980Sstevel@tonic-gate 	case SSL_AD_CERTIFICATE_REVOKED:return(SSL3_AD_CERTIFICATE_REVOKED);
6990Sstevel@tonic-gate 	case SSL_AD_CERTIFICATE_EXPIRED:return(SSL3_AD_CERTIFICATE_EXPIRED);
7000Sstevel@tonic-gate 	case SSL_AD_CERTIFICATE_UNKNOWN:return(SSL3_AD_CERTIFICATE_UNKNOWN);
7010Sstevel@tonic-gate 	case SSL_AD_ILLEGAL_PARAMETER:	return(SSL3_AD_ILLEGAL_PARAMETER);
7020Sstevel@tonic-gate 	case SSL_AD_UNKNOWN_CA:		return(SSL3_AD_BAD_CERTIFICATE);
7030Sstevel@tonic-gate 	case SSL_AD_ACCESS_DENIED:	return(SSL3_AD_HANDSHAKE_FAILURE);
7040Sstevel@tonic-gate 	case SSL_AD_DECODE_ERROR:	return(SSL3_AD_HANDSHAKE_FAILURE);
7050Sstevel@tonic-gate 	case SSL_AD_DECRYPT_ERROR:	return(SSL3_AD_HANDSHAKE_FAILURE);
7060Sstevel@tonic-gate 	case SSL_AD_EXPORT_RESTRICTION:	return(SSL3_AD_HANDSHAKE_FAILURE);
7070Sstevel@tonic-gate 	case SSL_AD_PROTOCOL_VERSION:	return(SSL3_AD_HANDSHAKE_FAILURE);
7080Sstevel@tonic-gate 	case SSL_AD_INSUFFICIENT_SECURITY:return(SSL3_AD_HANDSHAKE_FAILURE);
7090Sstevel@tonic-gate 	case SSL_AD_INTERNAL_ERROR:	return(SSL3_AD_HANDSHAKE_FAILURE);
7100Sstevel@tonic-gate 	case SSL_AD_USER_CANCELLED:	return(SSL3_AD_HANDSHAKE_FAILURE);
7110Sstevel@tonic-gate 	case SSL_AD_NO_RENEGOTIATION:	return(-1); /* Don't send it :-) */
7120Sstevel@tonic-gate 	default:			return(-1);
7130Sstevel@tonic-gate 		}
7140Sstevel@tonic-gate 	}
7150Sstevel@tonic-gate 
716