t1_enc.c revision 55714
1/* ssl/t1_enc.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to.  The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 *    notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 *    notice, this list of conditions and the following disclaimer in the
30 *    documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 *    must display the following acknowledgement:
33 *    "This product includes cryptographic software written by
34 *     Eric Young (eay@cryptsoft.com)"
35 *    The word 'cryptographic' can be left out if the rouines from the library
36 *    being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 *    the apps directory (application code) you must include an acknowledgement:
39 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include <openssl/comp.h>
61#include <openssl/md5.h>
62#include <openssl/sha.h>
63#include <openssl/evp.h>
64#include <openssl/hmac.h>
65#include "ssl_locl.h"
66
67static void tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
68			int sec_len, unsigned char *seed, int seed_len,
69			unsigned char *out, int olen)
70	{
71	int chunk,n;
72	unsigned int j;
73	HMAC_CTX ctx;
74	HMAC_CTX ctx_tmp;
75	unsigned char A1[HMAC_MAX_MD_CBLOCK];
76	unsigned int A1_len;
77
78	chunk=EVP_MD_size(md);
79
80	HMAC_Init(&ctx,sec,sec_len,md);
81	HMAC_Update(&ctx,seed,seed_len);
82	HMAC_Final(&ctx,A1,&A1_len);
83
84	n=0;
85	for (;;)
86		{
87		HMAC_Init(&ctx,NULL,0,NULL); /* re-init */
88		HMAC_Update(&ctx,A1,A1_len);
89		memcpy(&ctx_tmp,&ctx,sizeof(ctx)); /* Copy for A2 */ /* not needed for last one */
90		HMAC_Update(&ctx,seed,seed_len);
91
92		if (olen > chunk)
93			{
94			HMAC_Final(&ctx,out,&j);
95			out+=j;
96			olen-=j;
97			HMAC_Final(&ctx_tmp,A1,&A1_len); /* calc the next A1 value */
98			}
99		else	/* last one */
100			{
101			HMAC_Final(&ctx,A1,&A1_len);
102			memcpy(out,A1,olen);
103			break;
104			}
105		}
106	HMAC_cleanup(&ctx);
107	HMAC_cleanup(&ctx_tmp);
108	memset(A1,0,sizeof(A1));
109	}
110
111static void tls1_PRF(const EVP_MD *md5, const EVP_MD *sha1,
112		     unsigned char *label, int label_len,
113		     const unsigned char *sec, int slen, unsigned char *out1,
114		     unsigned char *out2, int olen)
115	{
116	int len,i;
117	const unsigned char *S1,*S2;
118
119	len=slen/2;
120	S1=sec;
121	S2= &(sec[len]);
122	len+=(slen&1); /* add for odd, make longer */
123
124
125	tls1_P_hash(md5 ,S1,len,label,label_len,out1,olen);
126	tls1_P_hash(sha1,S2,len,label,label_len,out2,olen);
127
128	for (i=0; i<olen; i++)
129		out1[i]^=out2[i];
130	}
131
132static void tls1_generate_key_block(SSL *s, unsigned char *km,
133	     unsigned char *tmp, int num)
134	{
135	unsigned char *p;
136	unsigned char buf[SSL3_RANDOM_SIZE*2+
137		TLS_MD_MAX_CONST_SIZE];
138	p=buf;
139
140	memcpy(p,TLS_MD_KEY_EXPANSION_CONST,
141		TLS_MD_KEY_EXPANSION_CONST_SIZE);
142	p+=TLS_MD_KEY_EXPANSION_CONST_SIZE;
143	memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
144	p+=SSL3_RANDOM_SIZE;
145	memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE);
146	p+=SSL3_RANDOM_SIZE;
147
148	tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(p-buf),
149		 s->session->master_key,s->session->master_key_length,
150		 km,tmp,num);
151	}
152
153int tls1_change_cipher_state(SSL *s, int which)
154	{
155	static const unsigned char empty[]="";
156	unsigned char *p,*key_block,*mac_secret;
157	unsigned char *exp_label,buf[TLS_MD_MAX_CONST_SIZE+
158		SSL3_RANDOM_SIZE*2];
159	unsigned char tmp1[EVP_MAX_KEY_LENGTH];
160	unsigned char tmp2[EVP_MAX_KEY_LENGTH];
161	unsigned char iv1[EVP_MAX_IV_LENGTH*2];
162	unsigned char iv2[EVP_MAX_IV_LENGTH*2];
163	unsigned char *ms,*key,*iv,*er1,*er2;
164	int client_write;
165	EVP_CIPHER_CTX *dd;
166	const EVP_CIPHER *c;
167	const SSL_COMP *comp;
168	const EVP_MD *m;
169	int _exp,n,i,j,k,exp_label_len,cl;
170
171	_exp=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
172	c=s->s3->tmp.new_sym_enc;
173	m=s->s3->tmp.new_hash;
174	comp=s->s3->tmp.new_compression;
175	key_block=s->s3->tmp.key_block;
176
177	if (which & SSL3_CC_READ)
178		{
179		if ((s->enc_read_ctx == NULL) &&
180			((s->enc_read_ctx=(EVP_CIPHER_CTX *)
181			Malloc(sizeof(EVP_CIPHER_CTX))) == NULL))
182			goto err;
183		dd= s->enc_read_ctx;
184		s->read_hash=m;
185		if (s->expand != NULL)
186			{
187			COMP_CTX_free(s->expand);
188			s->expand=NULL;
189			}
190		if (comp != NULL)
191			{
192			s->expand=COMP_CTX_new(comp->method);
193			if (s->expand == NULL)
194				{
195				SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
196				goto err2;
197				}
198			if (s->s3->rrec.comp == NULL)
199				s->s3->rrec.comp=(unsigned char *)
200					Malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH);
201			if (s->s3->rrec.comp == NULL)
202				goto err;
203			}
204		memset(&(s->s3->read_sequence[0]),0,8);
205		mac_secret= &(s->s3->read_mac_secret[0]);
206		}
207	else
208		{
209		if ((s->enc_write_ctx == NULL) &&
210			((s->enc_write_ctx=(EVP_CIPHER_CTX *)
211			Malloc(sizeof(EVP_CIPHER_CTX))) == NULL))
212			goto err;
213		dd= s->enc_write_ctx;
214		s->write_hash=m;
215		if (s->compress != NULL)
216			{
217			COMP_CTX_free(s->compress);
218			s->compress=NULL;
219			}
220		if (comp != NULL)
221			{
222			s->compress=COMP_CTX_new(comp->method);
223			if (s->compress == NULL)
224				{
225				SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
226				goto err2;
227				}
228			}
229		memset(&(s->s3->write_sequence[0]),0,8);
230		mac_secret= &(s->s3->write_mac_secret[0]);
231		}
232
233	EVP_CIPHER_CTX_init(dd);
234
235	p=s->s3->tmp.key_block;
236	i=EVP_MD_size(m);
237	cl=EVP_CIPHER_key_length(c);
238	j=_exp ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ?
239		  cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl;
240	/* Was j=(exp)?5:EVP_CIPHER_key_length(c); */
241	k=EVP_CIPHER_iv_length(c);
242	er1= &(s->s3->client_random[0]);
243	er2= &(s->s3->server_random[0]);
244	if (	(which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
245		(which == SSL3_CHANGE_CIPHER_SERVER_READ))
246		{
247		ms=  &(p[ 0]); n=i+i;
248		key= &(p[ n]); n+=j+j;
249		iv=  &(p[ n]); n+=k+k;
250		exp_label=(unsigned char *)TLS_MD_CLIENT_WRITE_KEY_CONST;
251		exp_label_len=TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE;
252		client_write=1;
253		}
254	else
255		{
256		n=i;
257		ms=  &(p[ n]); n+=i+j;
258		key= &(p[ n]); n+=j+k;
259		iv=  &(p[ n]); n+=k;
260		exp_label=(unsigned char *)TLS_MD_SERVER_WRITE_KEY_CONST;
261		exp_label_len=TLS_MD_SERVER_WRITE_KEY_CONST_SIZE;
262		client_write=0;
263		}
264
265	if (n > s->s3->tmp.key_block_length)
266		{
267		SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_INTERNAL_ERROR);
268		goto err2;
269		}
270
271	memcpy(mac_secret,ms,i);
272#ifdef TLS_DEBUG
273printf("which = %04X\nmac key=",which);
274{ int z; for (z=0; z<i; z++) printf("%02X%c",ms[z],((z+1)%16)?' ':'\n'); }
275#endif
276	if (_exp)
277		{
278		/* In here I set both the read and write key/iv to the
279		 * same value since only the correct one will be used :-).
280		 */
281		p=buf;
282		memcpy(p,exp_label,exp_label_len);
283		p+=exp_label_len;
284		memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE);
285		p+=SSL3_RANDOM_SIZE;
286		memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
287		p+=SSL3_RANDOM_SIZE;
288		tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(p-buf),key,j,
289			 tmp1,tmp2,EVP_CIPHER_key_length(c));
290		key=tmp1;
291
292		if (k > 0)
293			{
294			p=buf;
295			memcpy(p,TLS_MD_IV_BLOCK_CONST,
296				TLS_MD_IV_BLOCK_CONST_SIZE);
297			p+=TLS_MD_IV_BLOCK_CONST_SIZE;
298			memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE);
299			p+=SSL3_RANDOM_SIZE;
300			memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
301			p+=SSL3_RANDOM_SIZE;
302			tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,p-buf,empty,0,
303				 iv1,iv2,k*2);
304			if (client_write)
305				iv=iv1;
306			else
307				iv= &(iv1[k]);
308			}
309		}
310
311	s->session->key_arg_length=0;
312
313	EVP_CipherInit(dd,c,key,iv,(which & SSL3_CC_WRITE));
314#ifdef TLS_DEBUG
315printf("which = %04X\nkey=",which);
316{ int z; for (z=0; z<EVP_CIPHER_key_length(c); z++) printf("%02X%c",key[z],((z+1)%16)?' ':'\n'); }
317printf("\niv=");
318{ int z; for (z=0; z<k; z++) printf("%02X%c",iv[z],((z+1)%16)?' ':'\n'); }
319printf("\n");
320#endif
321
322	memset(tmp1,0,sizeof(tmp1));
323	memset(tmp2,0,sizeof(tmp1));
324	memset(iv1,0,sizeof(iv1));
325	memset(iv2,0,sizeof(iv2));
326	return(1);
327err:
328	SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE);
329err2:
330	return(0);
331	}
332
333int tls1_setup_key_block(SSL *s)
334	{
335	unsigned char *p1,*p2;
336	const EVP_CIPHER *c;
337	const EVP_MD *hash;
338	int num;
339	SSL_COMP *comp;
340
341	if (s->s3->tmp.key_block_length != 0)
342		return(1);
343
344	if (!ssl_cipher_get_evp(s->session,&c,&hash,&comp))
345		{
346		SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
347		return(0);
348		}
349
350	s->s3->tmp.new_sym_enc=c;
351	s->s3->tmp.new_hash=hash;
352
353	num=EVP_CIPHER_key_length(c)+EVP_MD_size(hash)+EVP_CIPHER_iv_length(c);
354	num*=2;
355
356	ssl3_cleanup_key_block(s);
357
358	if ((p1=(unsigned char *)Malloc(num)) == NULL)
359		goto err;
360	if ((p2=(unsigned char *)Malloc(num)) == NULL)
361		goto err;
362
363	s->s3->tmp.key_block_length=num;
364	s->s3->tmp.key_block=p1;
365
366
367#ifdef TLS_DEBUG
368printf("client random\n");
369{ int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) printf("%02X%c",s->s3->client_random[z],((z+1)%16)?' ':'\n'); }
370printf("server random\n");
371{ int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) printf("%02X%c",s->s3->server_random[z],((z+1)%16)?' ':'\n'); }
372printf("pre-master\n");
373{ int z; for (z=0; z<s->session->master_key_length; z++) printf("%02X%c",s->session->master_key[z],((z+1)%16)?' ':'\n'); }
374#endif
375	tls1_generate_key_block(s,p1,p2,num);
376	memset(p2,0,num);
377	Free(p2);
378#ifdef TLS_DEBUG
379printf("\nkey block\n");
380{ int z; for (z=0; z<num; z++) printf("%02X%c",p1[z],((z+1)%16)?' ':'\n'); }
381#endif
382
383	return(1);
384err:
385	SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE);
386	return(0);
387	}
388
389int tls1_enc(SSL *s, int send)
390	{
391	SSL3_RECORD *rec;
392	EVP_CIPHER_CTX *ds;
393	unsigned long l;
394	int bs,i,ii,j,k,n=0;
395	const EVP_CIPHER *enc;
396
397	if (send)
398		{
399		if (s->write_hash != NULL)
400			n=EVP_MD_size(s->write_hash);
401		ds=s->enc_write_ctx;
402		rec= &(s->s3->wrec);
403		if (s->enc_write_ctx == NULL)
404			enc=NULL;
405		else
406			enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
407		}
408	else
409		{
410		if (s->read_hash != NULL)
411			n=EVP_MD_size(s->read_hash);
412		ds=s->enc_read_ctx;
413		rec= &(s->s3->rrec);
414		if (s->enc_read_ctx == NULL)
415			enc=NULL;
416		else
417			enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
418		}
419
420	if ((s->session == NULL) || (ds == NULL) ||
421		(enc == NULL))
422		{
423		memcpy(rec->data,rec->input,rec->length);
424		rec->input=rec->data;
425		}
426	else
427		{
428		l=rec->length;
429		bs=EVP_CIPHER_block_size(ds->cipher);
430
431		if ((bs != 1) && send)
432			{
433			i=bs-((int)l%bs);
434
435			/* Add weird padding of upto 256 bytes */
436
437			/* we need to add 'i' padding bytes of value j */
438			j=i-1;
439			if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG)
440				{
441				if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
442					j++;
443				}
444			for (k=(int)l; k<(int)(l+i); k++)
445				rec->input[k]=j;
446			l+=i;
447			rec->length+=i;
448			}
449
450		EVP_Cipher(ds,rec->data,rec->input,l);
451
452		if ((bs != 1) && !send)
453			{
454			ii=i=rec->data[l-1];
455			i++;
456			if (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG)
457				{
458				/* First packet is even in size, so check */
459				if ((memcmp(s->s3->read_sequence,
460					"\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1))
461					s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG;
462				if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
463					i--;
464				}
465			if (i > (int)rec->length)
466				{
467				SSLerr(SSL_F_TLS1_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
468				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED);
469				return(0);
470				}
471			for (j=(int)(l-i); j<(int)l; j++)
472				{
473				if (rec->data[j] != ii)
474					{
475					SSLerr(SSL_F_TLS1_ENC,SSL_R_DECRYPTION_FAILED);
476					ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED);
477					return(0);
478					}
479				}
480			rec->length-=i;
481			}
482		}
483	return(1);
484	}
485
486int tls1_cert_verify_mac(SSL *s, EVP_MD_CTX *in_ctx, unsigned char *out)
487	{
488	unsigned int ret;
489	EVP_MD_CTX ctx;
490
491	EVP_MD_CTX_copy(&ctx,in_ctx);
492	EVP_DigestFinal(&ctx,out,&ret);
493	return((int)ret);
494	}
495
496int tls1_final_finish_mac(SSL *s, EVP_MD_CTX *in1_ctx, EVP_MD_CTX *in2_ctx,
497	     unsigned char *str, int slen, unsigned char *out)
498	{
499	unsigned int i;
500	EVP_MD_CTX ctx;
501	unsigned char buf[TLS_MD_MAX_CONST_SIZE+MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
502	unsigned char *q,buf2[12];
503
504	q=buf;
505	memcpy(q,str,slen);
506	q+=slen;
507
508	EVP_MD_CTX_copy(&ctx,in1_ctx);
509	EVP_DigestFinal(&ctx,q,&i);
510	q+=i;
511	EVP_MD_CTX_copy(&ctx,in2_ctx);
512	EVP_DigestFinal(&ctx,q,&i);
513	q+=i;
514
515	tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(q-buf),
516		s->session->master_key,s->session->master_key_length,
517		out,buf2,12);
518	memset(&ctx,0,sizeof(EVP_MD_CTX));
519
520	return((int)12);
521	}
522
523int tls1_mac(SSL *ssl, unsigned char *md, int send)
524	{
525	SSL3_RECORD *rec;
526	unsigned char *mac_sec,*seq;
527	const EVP_MD *hash;
528	unsigned int md_size;
529	int i;
530	HMAC_CTX hmac;
531	unsigned char buf[5];
532
533	if (send)
534		{
535		rec= &(ssl->s3->wrec);
536		mac_sec= &(ssl->s3->write_mac_secret[0]);
537		seq= &(ssl->s3->write_sequence[0]);
538		hash=ssl->write_hash;
539		}
540	else
541		{
542		rec= &(ssl->s3->rrec);
543		mac_sec= &(ssl->s3->read_mac_secret[0]);
544		seq= &(ssl->s3->read_sequence[0]);
545		hash=ssl->read_hash;
546		}
547
548	md_size=EVP_MD_size(hash);
549
550	buf[0]=rec->type;
551	buf[1]=TLS1_VERSION_MAJOR;
552	buf[2]=TLS1_VERSION_MINOR;
553	buf[3]=rec->length>>8;
554	buf[4]=rec->length&0xff;
555
556	/* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */
557	HMAC_Init(&hmac,mac_sec,EVP_MD_size(hash),hash);
558	HMAC_Update(&hmac,seq,8);
559	HMAC_Update(&hmac,buf,5);
560	HMAC_Update(&hmac,rec->input,rec->length);
561	HMAC_Final(&hmac,md,&md_size);
562
563#ifdef TLS_DEBUG
564printf("sec=");
565{unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",mac_sec[z]); printf("\n"); }
566printf("seq=");
567{int z; for (z=0; z<8; z++) printf("%02X ",seq[z]); printf("\n"); }
568printf("buf=");
569{int z; for (z=0; z<5; z++) printf("%02X ",buf[z]); printf("\n"); }
570printf("rec=");
571{unsigned int z; for (z=0; z<rec->length; z++) printf("%02X ",buf[z]); printf("\n"); }
572#endif
573
574	for (i=7; i>=0; i--)
575		if (++seq[i]) break;
576
577#ifdef TLS_DEBUG
578{unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",md[z]); printf("\n"); }
579#endif
580	return(md_size);
581	}
582
583int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
584	     int len)
585	{
586	unsigned char buf[SSL3_RANDOM_SIZE*2+TLS_MD_MASTER_SECRET_CONST_SIZE];
587	unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH];
588
589	/* Setup the stuff to munge */
590	memcpy(buf,TLS_MD_MASTER_SECRET_CONST,
591		TLS_MD_MASTER_SECRET_CONST_SIZE);
592	memcpy(&(buf[TLS_MD_MASTER_SECRET_CONST_SIZE]),
593		s->s3->client_random,SSL3_RANDOM_SIZE);
594	memcpy(&(buf[SSL3_RANDOM_SIZE+TLS_MD_MASTER_SECRET_CONST_SIZE]),
595		s->s3->server_random,SSL3_RANDOM_SIZE);
596	tls1_PRF(s->ctx->md5,s->ctx->sha1,
597		buf,TLS_MD_MASTER_SECRET_CONST_SIZE+SSL3_RANDOM_SIZE*2,p,len,
598		s->session->master_key,buff,SSL3_MASTER_SECRET_SIZE);
599	return(SSL3_MASTER_SECRET_SIZE);
600	}
601
602int tls1_alert_code(int code)
603	{
604	switch (code)
605		{
606	case SSL_AD_CLOSE_NOTIFY:	return(SSL3_AD_CLOSE_NOTIFY);
607	case SSL_AD_UNEXPECTED_MESSAGE:	return(SSL3_AD_UNEXPECTED_MESSAGE);
608	case SSL_AD_BAD_RECORD_MAC:	return(SSL3_AD_BAD_RECORD_MAC);
609	case SSL_AD_DECRYPTION_FAILED:	return(TLS1_AD_DECRYPTION_FAILED);
610	case SSL_AD_RECORD_OVERFLOW:	return(TLS1_AD_RECORD_OVERFLOW);
611	case SSL_AD_DECOMPRESSION_FAILURE:return(SSL3_AD_DECOMPRESSION_FAILURE);
612	case SSL_AD_HANDSHAKE_FAILURE:	return(SSL3_AD_HANDSHAKE_FAILURE);
613	case SSL_AD_NO_CERTIFICATE:	return(-1);
614	case SSL_AD_BAD_CERTIFICATE:	return(SSL3_AD_BAD_CERTIFICATE);
615	case SSL_AD_UNSUPPORTED_CERTIFICATE:return(SSL3_AD_UNSUPPORTED_CERTIFICATE);
616	case SSL_AD_CERTIFICATE_REVOKED:return(SSL3_AD_CERTIFICATE_REVOKED);
617	case SSL_AD_CERTIFICATE_EXPIRED:return(SSL3_AD_CERTIFICATE_EXPIRED);
618	case SSL_AD_CERTIFICATE_UNKNOWN:return(SSL3_AD_CERTIFICATE_UNKNOWN);
619	case SSL_AD_ILLEGAL_PARAMETER:	return(SSL3_AD_ILLEGAL_PARAMETER);
620	case SSL_AD_UNKNOWN_CA:		return(TLS1_AD_UNKNOWN_CA);
621	case SSL_AD_ACCESS_DENIED:	return(TLS1_AD_ACCESS_DENIED);
622	case SSL_AD_DECODE_ERROR:	return(TLS1_AD_DECODE_ERROR);
623	case SSL_AD_DECRYPT_ERROR:	return(TLS1_AD_DECRYPT_ERROR);
624	case SSL_AD_EXPORT_RESTRICION:	return(TLS1_AD_EXPORT_RESTRICION);
625	case SSL_AD_PROTOCOL_VERSION:	return(TLS1_AD_PROTOCOL_VERSION);
626	case SSL_AD_INSUFFICIENT_SECURITY:return(TLS1_AD_INSUFFICIENT_SECURITY);
627	case SSL_AD_INTERNAL_ERROR:	return(TLS1_AD_INTERNAL_ERROR);
628	case SSL_AD_USER_CANCLED:	return(TLS1_AD_USER_CANCLED);
629	case SSL_AD_NO_RENEGOTIATION:	return(TLS1_AD_NO_RENEGOTIATION);
630	default:			return(-1);
631		}
632	}
633
634