If we're going to return errors (no matter how stupid), then we should
test for them!
diff --git a/ssl/d1_enc.c b/ssl/d1_enc.c
index ea5e12e..9de787e 100644
--- a/ssl/d1_enc.c
+++ b/ssl/d1_enc.c
@@ -135,7 +135,11 @@
 	if (send)
 		{
 		if (EVP_MD_CTX_md(s->write_hash))
+			{
 			n=EVP_MD_CTX_size(s->write_hash);
+			if (n < 0)
+				return -1;
+			}
 		ds=s->enc_write_ctx;
 		rec= &(s->s3->wrec);
 		if (s->enc_write_ctx == NULL)
@@ -157,7 +161,11 @@
 	else
 		{
 		if (EVP_MD_CTX_md(s->read_hash))
+			{
 			n=EVP_MD_CTX_size(s->read_hash);
+			if (n < 0)
+				return -1;
+			}
 		ds=s->enc_read_ctx;
 		rec= &(s->s3->rrec);
 		if (s->enc_read_ctx == NULL)
diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c
index daf1fee..dea63d6 100644
--- a/ssl/d1_pkt.c
+++ b/ssl/d1_pkt.c
@@ -428,7 +428,10 @@
 	if (!clear)
 		{
 		/* !clear => s->read_hash != NULL => mac_size != -1 */
-		mac_size=EVP_MD_CTX_size(s->read_hash);
+		int t;
+		t=EVP_MD_CTX_size(s->read_hash);
+		OPENSSL_assert(t >= 0);
+		mac_size=t;
 
 		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size)
 			{
@@ -453,7 +456,7 @@
 			}
 		rr->length-=mac_size;
 		i=s->method->ssl3_enc->mac(s,md,0);
-		if (memcmp(md,&(rr->data[rr->length]),mac_size) != 0)
+		if (i < 0 || memcmp(md,&(rr->data[rr->length]),mac_size) != 0)
 			{
 			goto decryption_failed_or_bad_record_mac;
 			}
@@ -1341,7 +1344,11 @@
 	if (clear)
 		mac_size=0;
 	else
+		{
 		mac_size=EVP_MD_CTX_size(s->write_hash);
+		if (mac_size < 0)
+			goto err;
+		}
 
 	/* DTLS implements explicit IV, so no need for empty fragments */
 #if 0
@@ -1428,7 +1435,8 @@
 
 	if (mac_size != 0)
 		{
-		s->method->ssl3_enc->mac(s,&(p[wr->length + bs]),1);
+		if(s->method->ssl3_enc->mac(s,&(p[wr->length + bs]),1) < 0)
+			goto err;
 		wr->length+=mac_size;
 		}
 
diff --git a/ssl/s2_lib.c b/ssl/s2_lib.c
index 4cfafce..907e305 100644
--- a/ssl/s2_lib.c
+++ b/ssl/s2_lib.c
@@ -455,6 +455,7 @@
 	unsigned char *km;
 	unsigned char c='0';
 	const EVP_MD *md5;
+	int md_size;
 
 	md5 = EVP_md5();
 
@@ -471,10 +472,12 @@
  		SSLerr(SSL_F_SSL2_GENERATE_KEY_MATERIAL, ERR_R_INTERNAL_ERROR);
  		return 0;
  		}
-
-	for (i=0; i<s->s2->key_material_length; i += EVP_MD_size(md5))
+	md_size = EVP_MD_size(md5);
+	if (md_size < 0)
+	    return 0;
+	for (i=0; i<s->s2->key_material_length; i += md_size)
 		{
-		if (((km - s->s2->key_material) + EVP_MD_size(md5)) >
+		if (((km - s->s2->key_material) + md_size) >
 				(int)sizeof(s->s2->key_material))
 			{
 			/* EVP_DigestFinal_ex() below would write beyond buffer */
@@ -493,7 +496,7 @@
 		EVP_DigestUpdate(&ctx,s->s2->challenge,s->s2->challenge_length);
 		EVP_DigestUpdate(&ctx,s->s2->conn_id,s->s2->conn_id_length);
 		EVP_DigestFinal_ex(&ctx,km,NULL);
-		km += EVP_MD_size(md5);
+		km += md_size;
 		}
 
 	EVP_MD_CTX_cleanup(&ctx);
diff --git a/ssl/s2_pkt.c b/ssl/s2_pkt.c
index e6d5d09..9c1d131 100644
--- a/ssl/s2_pkt.c
+++ b/ssl/s2_pkt.c
@@ -116,7 +116,7 @@
 #define USE_SOCKETS
 
 static int read_n(SSL *s,unsigned int n,unsigned int max,unsigned int extend);
-static int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len);
+static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len);
 static int write_pending(SSL *s, const unsigned char *buf, unsigned int len);
 static int ssl_mt_error(int n);
 
@@ -130,7 +130,7 @@
 	unsigned char mac[MAX_MAC_SIZE];
 	unsigned char *p;
 	int i;
-	unsigned int mac_size;
+	int mac_size;
 
  ssl2_read_again:
 	if (SSL_in_init(s) && !s->in_handshake)
@@ -247,6 +247,8 @@
 		else
 			{
 			mac_size=EVP_MD_CTX_size(s->read_hash);
+			if (mac_size < 0)
+				return -1;
 			OPENSSL_assert(mac_size <= MAX_MAC_SIZE);
 			s->s2->mac_data=p;
 			s->s2->ract_data= &p[mac_size];
@@ -447,7 +449,7 @@
 	n=(len-tot);
 	for (;;)
 		{
-		i=do_ssl_write(s,&(buf[tot]),n);
+		i=n_do_ssl_write(s,&(buf[tot]),n);
 		if (i <= 0)
 			{
 			s->s2->wnum=tot;
@@ -511,7 +513,7 @@
 		}
 	}
 
-static int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len)
+static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len)
 	{
 	unsigned int j,k,olen,p,mac_size,bs;
 	register unsigned char *pp;
@@ -529,7 +531,11 @@
 	if (s->s2->clear_text)
 		mac_size=0;
 	else
+		{
 		mac_size=EVP_MD_CTX_size(s->write_hash);
+		if (mac_size < 0)
+			return -1;
+		}
 
 	/* lets set the pad p */
 	if (s->s2->clear_text)
diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
index 96e59f6..00fad17 100644
--- a/ssl/s3_enc.c
+++ b/ssl/s3_enc.c
@@ -315,6 +315,8 @@
 
 	p=s->s3->tmp.key_block;
 	i=EVP_MD_size(m);
+	if (i < 0)
+		goto err2;
 	cl=EVP_CIPHER_key_length(c);
 	j=is_exp ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ?
 		 cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl;
@@ -409,7 +411,11 @@
 	s->s3->tmp.new_compression=comp;
 #endif
 
-	num=EVP_CIPHER_key_length(c)+EVP_MD_size(hash)+EVP_CIPHER_iv_length(c);
+	num=EVP_MD_size(hash);
+	if (num < 0)
+		return 0;
+
+	num=EVP_CIPHER_key_length(c)+num+EVP_CIPHER_iv_length(c);
 	num*=2;
 
 	ssl3_cleanup_key_block(s);
@@ -666,6 +672,9 @@
 	EVP_MD_CTX_init(&ctx);
 	EVP_MD_CTX_copy_ex(&ctx,d);
 	n=EVP_MD_CTX_size(&ctx);
+	if (n < 0)
+		return 0;
+
 	npad=(48/n)*n;
 	if (sender != NULL)
 		EVP_DigestUpdate(&ctx,sender,len);
@@ -686,7 +695,7 @@
 	return((int)ret);
 	}
 
-int ssl3_mac(SSL *ssl, unsigned char *md, int send)
+int n_ssl3_mac(SSL *ssl, unsigned char *md, int send)
 	{
 	SSL3_RECORD *rec;
 	unsigned char *mac_sec,*seq;
@@ -695,6 +704,7 @@
 	unsigned char *p,rec_char;
 	unsigned int md_size;
 	int npad;
+	int t;
 
 	if (send)
 		{
@@ -711,9 +721,10 @@
 		hash=ssl->read_hash;
 		}
 
-	/* If hash is NULL, then a crash will follow anyway */
-	OPENSSL_assert(hash);
-	md_size=EVP_MD_CTX_size(hash);
+	t=EVP_MD_CTX_size(hash);
+	if (t < 0)
+		return -1;
+	md_size=t;
 	npad=(48/md_size)*md_size;
 
 	/* Chop the digest off the end :-) */
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 54c0540..727827f 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -2077,7 +2077,7 @@
 
 SSL3_ENC_METHOD SSLv3_enc_data={
 	ssl3_enc,
-	ssl3_mac,
+	n_ssl3_mac,
 	ssl3_setup_key_block,
 	ssl3_generate_master_secret,
 	ssl3_change_cipher_state,
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
index 330918a..e6c68b3 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -414,6 +414,7 @@
 		{
 		/* !clear => s->read_hash != NULL => mac_size != -1 */
 		mac_size=EVP_MD_CTX_size(s->read_hash);
+		OPENSSL_assert(mac_size >= 0);
 
 		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size)
 			{
@@ -444,7 +445,7 @@
 #endif
 			}
 		i=s->method->ssl3_enc->mac(s,md,0);
-		if (mac == NULL || memcmp(md, mac, mac_size) != 0)
+		if (i < 0 || mac == NULL || memcmp(md, mac, mac_size) != 0)
 			{
 			decryption_failed_or_bad_record_mac = 1;
 			}
@@ -649,7 +650,11 @@
 	if (clear)
 		mac_size=0;
 	else
+		{
 		mac_size=EVP_MD_CTX_size(s->write_hash);
+		if (mac_size < 0)
+			goto err;
+		}
 
 	/* 'create_empty_fragment' is true only when this function calls itself */
 	if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done)
@@ -747,7 +752,8 @@
 
 	if (mac_size != 0)
 		{
-		s->method->ssl3_enc->mac(s,&(p[wr->length]),1);
+		if (s->method->ssl3_enc->mac(s,&(p[wr->length]),1) < 0)
+			goto err;
 		wr->length+=mac_size;
 		wr->input=p;
 		wr->data=p;
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index 5cc3a19..d732764 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -522,6 +522,7 @@
 				{
 				int offset=0;
 				int dgst_num;
+
 				s->state=SSL3_ST_SR_CERT_VRFY_A;
 				s->init_num=0;
 
@@ -536,8 +537,16 @@
 				for (dgst_num=0; dgst_num<SSL_MAX_DIGEST;dgst_num++)	
 					if (s->s3->handshake_dgst[dgst_num]) 
 						{
+						int dgst_size;
+
 						s->method->ssl3_enc->cert_verify_mac(s,EVP_MD_CTX_type(s->s3->handshake_dgst[dgst_num]),&(s->s3->tmp.cert_verify_md[offset]));
-						offset+=EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]);
+						dgst_size=EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]);
+						if (dgst_size < 0)
+							{
+							ret = -1;
+							goto end;
+							}
+						offset+=dgst_size;
 						}		
 				}
 			break;
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index 02cf181..8858dcb 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -381,16 +381,19 @@
 		EVP_get_digestbyname(SN_md5);
 	ssl_mac_secret_size[SSL_MD_MD5_IDX]=
 		EVP_MD_size(ssl_digest_methods[SSL_MD_MD5_IDX]);
+	OPENSSL_assert(ssl_mac_secret_size[SSL_MD_MD5_IDX] >= 0);
 	ssl_digest_methods[SSL_MD_SHA1_IDX]=
 		EVP_get_digestbyname(SN_sha1);
 	ssl_mac_secret_size[SSL_MD_SHA1_IDX]=
 		EVP_MD_size(ssl_digest_methods[SSL_MD_SHA1_IDX]);
+	OPENSSL_assert(ssl_mac_secret_size[SSL_MD_SHA1_IDX] >= 0);
 	ssl_digest_methods[SSL_MD_GOST94_IDX]=
 		EVP_get_digestbyname(SN_id_GostR3411_94);
 	if (ssl_digest_methods[SSL_MD_GOST94_IDX])
 		{	
 		ssl_mac_secret_size[SSL_MD_GOST94_IDX]=
 			EVP_MD_size(ssl_digest_methods[SSL_MD_GOST94_IDX]);
+		OPENSSL_assert(ssl_mac_secret_size[SSL_MD_GOST94_IDX] >= 0);
 		}
 	ssl_digest_methods[SSL_MD_GOST89MAC_IDX]=
 		EVP_get_digestbyname(SN_id_Gost28147_89_MAC);
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 9df4be5..2e6e98f 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -870,7 +870,7 @@
 int ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p);
 void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len);
 int ssl3_enc(SSL *s, int send_data);
-int ssl3_mac(SSL *ssl, unsigned char *md, int send_data);
+int n_ssl3_mac(SSL *ssl, unsigned char *md, int send_data);
 void ssl3_free_digest_list(SSL *s);
 unsigned long ssl3_output_cert_chain(SSL *s, X509 *x);
 SSL_CIPHER *ssl3_choose_cipher(SSL *ssl,STACK_OF(SSL_CIPHER) *clnt,
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index 4d9a18e..ea3cd71 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -163,6 +163,7 @@
 	unsigned int A1_len;
 	
 	chunk=EVP_MD_size(md);
+	OPENSSL_assert(chunk >= 0);
 
 	HMAC_CTX_init(&ctx);
 	HMAC_CTX_init(&ctx_tmp);
@@ -605,7 +606,10 @@
 	if (send)
 		{
 		if (EVP_MD_CTX_md(s->write_hash))
+			{
 			n=EVP_MD_CTX_size(s->write_hash);
+			OPENSSL_assert(n >= 0);
+			}
 		ds=s->enc_write_ctx;
 		rec= &(s->s3->wrec);
 		if (s->enc_write_ctx == NULL)
@@ -616,7 +620,10 @@
 	else
 		{
 		if (EVP_MD_CTX_md(s->read_hash))
+			{
 			n=EVP_MD_CTX_size(s->read_hash);
+			OPENSSL_assert(n >= 0);
+			}
 		ds=s->enc_read_ctx;
 		rec= &(s->s3->rrec);
 		if (s->enc_read_ctx == NULL)
@@ -796,8 +803,8 @@
 		{
 		if (mask & s->s3->tmp.new_cipher->algorithm2)
 			{
-			unsigned int hashsize = EVP_MD_size(md);
-			if (hashsize > (sizeof buf - (size_t)(q-buf)))
+			int hashsize = EVP_MD_size(md);
+			if (hashsize < 0 || hashsize > (sizeof buf - (size_t)(q-buf)))
 				{
 				/* internal error: 'buf' is too small for this cipersuite! */
 				err = 1;
@@ -835,6 +842,7 @@
 	EVP_MD_CTX hmac, *mac_ctx;
 	unsigned char buf[5]; 
 	int stream_mac = (send?(ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM):(ssl->mac_flags&SSL_MAC_FLAG_READ_MAC_STREAM));
+	int t;
 
 	if (send)
 		{
@@ -851,7 +859,9 @@
 		hash=ssl->read_hash;
 		}
 
-	md_size=EVP_MD_CTX_size(hash);
+	t=EVP_MD_CTX_size(hash);
+	OPENSSL_assert(t >= 0);
+	md_size=t;
 
 	buf[0]=rec->type;
 	buf[1]=(unsigned char)(ssl->version>>8);
@@ -884,7 +894,9 @@
 
 	EVP_DigestSignUpdate(mac_ctx,buf,5);
 	EVP_DigestSignUpdate(mac_ctx,rec->input,rec->length);
-	EVP_DigestSignFinal(mac_ctx,md,&md_size);
+	t=EVP_DigestSignFinal(mac_ctx,md,&md_size);
+	OPENSSL_assert(t > 0);
+		
 	if (!stream_mac) EVP_MD_CTX_cleanup(&hmac);
 #ifdef TLS_DEBUG
 printf("sec=");
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index e6ba33d..c1d4173 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -1532,6 +1532,11 @@
  	 * integrity checks on ticket.
  	 */
 	mlen = HMAC_size(&hctx);
+	if (mlen < 0)
+		{
+		EVP_CIPHER_CTX_cleanup(&ctx);
+		return -1;
+		}
 	eticklen -= mlen;
 	/* Check HMAC of encrypted ticket */
 	HMAC_Update(&hctx, etick, eticklen);