summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGES5
-rw-r--r--ssl/d1_enc.c8
-rw-r--r--ssl/d1_pkt.c6
-rw-r--r--ssl/s2_clnt.c2
-rw-r--r--ssl/s2_enc.c9
-rw-r--r--ssl/s2_pkt.c4
-rw-r--r--ssl/s2_srvr.c2
-rw-r--r--ssl/s3_enc.c16
-rw-r--r--ssl/s3_lib.c42
-rw-r--r--ssl/s3_pkt.c8
-rw-r--r--ssl/ssl.h11
-rw-r--r--ssl/ssl3.h4
-rw-r--r--ssl/ssl_ciph.c73
-rw-r--r--ssl/ssl_lib.c28
-rw-r--r--ssl/ssl_locl.h7
-rw-r--r--ssl/ssl_txt.c2
-rw-r--r--ssl/t1_enc.c76
-rw-r--r--ssl/tls1.h4
18 files changed, 242 insertions, 65 deletions
diff --git a/CHANGES b/CHANGES
index 0a383b44f2..6af082f362 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,11 @@
Changes between 0.9.8f and 0.9.9 [xx XXX xxxx]
+ *) Update SSL library to use new EVP_PKEY MAC API. Include generic MAC
+ support including streaming MAC support: this is required for GOST
+ ciphersuite support.
+ [Victor B. Wagner <vitus@cryptocom.ru>, Steve Henson]
+
*) Add option -stream to use PKCS#7 streaming in smime utility. New
function i2d_PKCS7_bio_stream() and PEM_write_PKCS7_bio_stream()
to output in BER and PEM format.
diff --git a/ssl/d1_enc.c b/ssl/d1_enc.c
index cbff7495c5..ef4d880551 100644
--- a/ssl/d1_enc.c
+++ b/ssl/d1_enc.c
@@ -132,8 +132,8 @@ int dtls1_enc(SSL *s, int send)
if (send)
{
- if (s->write_hash != NULL)
- n=EVP_MD_size(s->write_hash);
+ if (EVP_MD_CTX_md(s->write_hash))
+ n=EVP_MD_CTX_size(s->write_hash);
ds=s->enc_write_ctx;
rec= &(s->s3->wrec);
if (s->enc_write_ctx == NULL)
@@ -154,8 +154,8 @@ int dtls1_enc(SSL *s, int send)
}
else
{
- if (s->read_hash != NULL)
- n=EVP_MD_size(s->read_hash);
+ if (EVP_MD_CTX_md(s->read_hash))
+ n=EVP_MD_CTX_size(s->read_hash);
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 8a047aeda7..bf189f11c3 100644
--- a/ssl/d1_pkt.c
+++ b/ssl/d1_pkt.c
@@ -426,7 +426,7 @@ printf("\n");
if (!clear)
{
- mac_size=EVP_MD_size(s->read_hash);
+ mac_size=EVP_MD_CTX_size(s->read_hash);
if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size)
{
@@ -1335,13 +1335,13 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len,
if ( (sess == NULL) ||
(s->enc_write_ctx == NULL) ||
- (s->write_hash == NULL))
+ (EVP_MD_CTX_md(s->write_hash) == NULL))
clear=1;
if (clear)
mac_size=0;
else
- mac_size=EVP_MD_size(s->write_hash);
+ mac_size=EVP_MD_CTX_size(s->write_hash);
/* DTLS implements explicit IV, so no need for empty fragments */
#if 0
diff --git a/ssl/s2_clnt.c b/ssl/s2_clnt.c
index 6d8883fbbd..7b3b7d8eac 100644
--- a/ssl/s2_clnt.c
+++ b/ssl/s2_clnt.c
@@ -621,7 +621,7 @@ static int client_master_key(SSL *s)
if (s->state == SSL2_ST_SEND_CLIENT_MASTER_KEY_A)
{
- if (!ssl_cipher_get_evp(s->session,&c,&md,NULL))
+ if (!ssl_cipher_get_evp(s->session,&c,&md,NULL,NULL,NULL))
{
ssl2_return_error(s,SSL2_PE_NO_CIPHER);
SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS);
diff --git a/ssl/s2_enc.c b/ssl/s2_enc.c
index 1f62acd5b1..ff3395f459 100644
--- a/ssl/s2_enc.c
+++ b/ssl/s2_enc.c
@@ -68,15 +68,14 @@ int ssl2_enc_init(SSL *s, int client)
const EVP_MD *md;
int num;
- if (!ssl_cipher_get_evp(s->session,&c,&md,NULL))
+ if (!ssl_cipher_get_evp(s->session,&c,&md,NULL,NULL,NULL))
{
ssl2_return_error(s,SSL2_PE_NO_CIPHER);
SSLerr(SSL_F_SSL2_ENC_INIT,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS);
return(0);
}
-
- s->read_hash=md;
- s->write_hash=md;
+ ssl_replace_hash(&s->read_hash,md);
+ ssl_replace_hash(&s->write_hash,md);
if ((s->enc_read_ctx == NULL) &&
((s->enc_read_ctx=(EVP_CIPHER_CTX *)
@@ -176,7 +175,7 @@ void ssl2_mac(SSL *s, unsigned char *md, int send)
/* There has to be a MAC algorithm. */
EVP_MD_CTX_init(&c);
- EVP_DigestInit_ex(&c, s->read_hash, NULL);
+ EVP_MD_CTX_copy(&c, s->read_hash);
EVP_DigestUpdate(&c,sec,
EVP_CIPHER_CTX_key_length(s->enc_read_ctx));
EVP_DigestUpdate(&c,act,len);
diff --git a/ssl/s2_pkt.c b/ssl/s2_pkt.c
index a10929a757..e6d5d09643 100644
--- a/ssl/s2_pkt.c
+++ b/ssl/s2_pkt.c
@@ -246,7 +246,7 @@ static int ssl2_read_internal(SSL *s, void *buf, int len, int peek)
}
else
{
- mac_size=EVP_MD_size(s->read_hash);
+ mac_size=EVP_MD_CTX_size(s->read_hash);
OPENSSL_assert(mac_size <= MAX_MAC_SIZE);
s->s2->mac_data=p;
s->s2->ract_data= &p[mac_size];
@@ -529,7 +529,7 @@ static int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len)
if (s->s2->clear_text)
mac_size=0;
else
- mac_size=EVP_MD_size(s->write_hash);
+ mac_size=EVP_MD_CTX_size(s->write_hash);
/* lets set the pad p */
if (s->s2->clear_text)
diff --git a/ssl/s2_srvr.c b/ssl/s2_srvr.c
index 45943240f0..44c1ee3527 100644
--- a/ssl/s2_srvr.c
+++ b/ssl/s2_srvr.c
@@ -451,7 +451,7 @@ static int get_client_master_key(SSL *s)
is_export=SSL_C_IS_EXPORT(s->session->cipher);
- if (!ssl_cipher_get_evp(s->session,&c,&md,NULL))
+ if (!ssl_cipher_get_evp(s->session,&c,&md,NULL,NULL,NULL))
{
ssl2_return_error(s,SSL2_PE_NO_CIPHER);
SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS);
diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
index 8f3ba93d61..010069bf28 100644
--- a/ssl/s3_enc.c
+++ b/ssl/s3_enc.c
@@ -251,7 +251,8 @@ int ssl3_change_cipher_state(SSL *s, int which)
/* make sure it's intialized in case we exit later with an error */
EVP_CIPHER_CTX_init(s->enc_read_ctx);
dd= s->enc_read_ctx;
- s->read_hash=m;
+
+ ssl_replace_hash(&s->read_hash,m);
#ifndef OPENSSL_NO_COMP
/* COMPRESS */
if (s->expand != NULL)
@@ -287,7 +288,7 @@ int ssl3_change_cipher_state(SSL *s, int which)
/* make sure it's intialized in case we exit later with an error */
EVP_CIPHER_CTX_init(s->enc_write_ctx);
dd= s->enc_write_ctx;
- s->write_hash=m;
+ ssl_replace_hash(&s->write_hash,m);
#ifndef OPENSSL_NO_COMP
/* COMPRESS */
if (s->compress != NULL)
@@ -394,7 +395,7 @@ int ssl3_setup_key_block(SSL *s)
if (s->s3->tmp.key_block_length != 0)
return(1);
- if (!ssl_cipher_get_evp(s->session,&c,&hash,&comp))
+ if (!ssl_cipher_get_evp(s->session,&c,&hash,NULL,NULL,&comp))
{
SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
return(0);
@@ -581,7 +582,6 @@ static int ssl3_handshake_mac(SSL *s, EVP_MD_CTX *in_ctx,
EVP_MD_CTX_init(&ctx);
EVP_MD_CTX_copy_ex(&ctx,in_ctx);
-
n=EVP_MD_CTX_size(&ctx);
npad=(48/n)*n;
@@ -609,7 +609,7 @@ int ssl3_mac(SSL *ssl, unsigned char *md, int send)
SSL3_RECORD *rec;
unsigned char *mac_sec,*seq;
EVP_MD_CTX md_ctx;
- const EVP_MD *hash;
+ const EVP_MD_CTX *hash;
unsigned char *p,rec_char;
unsigned int md_size;
int npad;
@@ -629,13 +629,13 @@ int ssl3_mac(SSL *ssl, unsigned char *md, int send)
hash=ssl->read_hash;
}
- md_size=EVP_MD_size(hash);
+ md_size=EVP_MD_CTX_size(hash);
npad=(48/md_size)*md_size;
/* Chop the digest off the end :-) */
EVP_MD_CTX_init(&md_ctx);
- EVP_DigestInit_ex( &md_ctx,hash, NULL);
+ EVP_MD_CTX_copy_ex( &md_ctx,hash);
EVP_DigestUpdate(&md_ctx,mac_sec,md_size);
EVP_DigestUpdate(&md_ctx,ssl3_pad_1,npad);
EVP_DigestUpdate(&md_ctx,seq,8);
@@ -647,7 +647,7 @@ int ssl3_mac(SSL *ssl, unsigned char *md, int send)
EVP_DigestUpdate(&md_ctx,rec->input,rec->length);
EVP_DigestFinal_ex( &md_ctx,md,NULL);
- EVP_DigestInit_ex( &md_ctx,hash, NULL);
+ EVP_MD_CTX_copy_ex( &md_ctx,hash);
EVP_DigestUpdate(&md_ctx,mac_sec,md_size);
EVP_DigestUpdate(&md_ctx,ssl3_pad_2,npad);
EVP_DigestUpdate(&md_ctx,md,md_size);
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 4ac696111f..bd0056b9fe 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -1972,6 +1972,48 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
256,
256,
},
+ {
+ 1,
+ "GOST-GOST94",
+ 0x0300ff01,
+ SSL_kRSA,
+ SSL_aRSA,
+ SSL_eGOST2814789CNT,
+ SSL_GOST94,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH,
+ 0,
+ 256,
+ 256
+ },
+ {
+ 1,
+ "GOST-GOST89MAC",
+ 0x0300ff02,
+ SSL_kRSA,
+ SSL_aRSA,
+ SSL_eGOST2814789CNT,
+ SSL_GOST89MAC,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH,
+ 0,
+ 256,
+ 256
+ },
+ {
+ 1,
+ "GOST-GOST89STREAM",
+ 0x0300ff03,
+ SSL_kRSA,
+ SSL_aRSA,
+ SSL_eGOST2814789CNT,
+ SSL_GOST89MAC,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH,
+ TLS1_STREAM_MAC,
+ 256,
+ 256
+ },
#endif
/* end of list */
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
index 6754e993c5..58f2845d6e 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -399,12 +399,12 @@ printf("\n");
/* r->length is now the compressed data plus mac */
if ( (sess == NULL) ||
(s->enc_read_ctx == NULL) ||
- (s->read_hash == NULL))
+ (EVP_MD_CTX_md(s->read_hash) == NULL))
clear=1;
if (!clear)
{
- mac_size=EVP_MD_size(s->read_hash);
+ mac_size=EVP_MD_CTX_size(s->read_hash);
if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size)
{
@@ -629,13 +629,13 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
if ( (sess == NULL) ||
(s->enc_write_ctx == NULL) ||
- (s->write_hash == NULL))
+ (EVP_MD_CTX_md(s->write_hash) == NULL))
clear=1;
if (clear)
mac_size=0;
else
- mac_size=EVP_MD_size(s->write_hash);
+ mac_size=EVP_MD_CTX_size(s->write_hash);
/* 'create_empty_fragment' is true only when this function calls itself */
if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done)
diff --git a/ssl/ssl.h b/ssl/ssl.h
index abc3342dbe..5702464069 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -286,6 +286,8 @@ extern "C" {
#define SSL_TXT_MD5 "MD5"
#define SSL_TXT_SHA1 "SHA1"
#define SSL_TXT_SHA "SHA" /* same as "SHA1" */
+#define SSL_TXT_GOST94 "GOST94"
+#define SSL_TXT_GOST89MAC "GOST89MAC"
#define SSL_TXT_SSLV2 "SSLv2"
#define SSL_TXT_SSLV3 "SSLv3"
@@ -884,6 +886,9 @@ const char *SSL_get_psk_identity(const SSL *s);
#define SSL_want_write(s) (SSL_want(s) == SSL_WRITING)
#define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP)
+#define SSL_MAC_FLAG_READ_MAC_STREAM 1
+#define SSL_MAC_FLAG_WRITE_MAC_STREAM 2
+
struct ssl_st
{
/* protocol version
@@ -975,9 +980,9 @@ struct ssl_st
/* These are the ones being used, the ones in SSL_SESSION are
* the ones to be 'copied' into these ones */
-
+ int mac_flags;
EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */
- const EVP_MD *read_hash; /* used for mac generation */
+ EVP_MD_CTX *read_hash; /* used for mac generation */
#ifndef OPENSSL_NO_COMP
COMP_CTX *expand; /* uncompress */
#else
@@ -985,7 +990,7 @@ struct ssl_st
#endif
EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */
- const EVP_MD *write_hash; /* used for mac generation */
+ EVP_MD_CTX *write_hash; /* used for mac generation */
#ifndef OPENSSL_NO_COMP
COMP_CTX *compress; /* compression */
#else
diff --git a/ssl/ssl3.h b/ssl/ssl3.h
index 5ddadb2cd1..2d5db780be 100644
--- a/ssl/ssl3.h
+++ b/ssl/ssl3.h
@@ -382,8 +382,10 @@ typedef struct ssl3_state_st
int delay_buf_pop_ret;
unsigned char read_sequence[8];
+ int read_mac_secret_size;
unsigned char read_mac_secret[EVP_MAX_MD_SIZE];
unsigned char write_sequence[8];
+ int write_mac_secret_size;
unsigned char write_mac_secret[EVP_MAX_MD_SIZE];
unsigned char server_random[SSL3_RANDOM_SIZE];
@@ -480,6 +482,8 @@ typedef struct ssl3_state_st
const EVP_CIPHER *new_sym_enc;
const EVP_MD *new_hash;
+ int new_mac_pkey_type;
+ int new_mac_secret_size;
#ifndef OPENSSL_NO_COMP
const SSL_COMP *new_compression;
#else
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index 0a56042931..d2e648bf30 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -143,6 +143,7 @@
#include <stdio.h>
#include <openssl/objects.h>
#include <openssl/comp.h>
+#include <openssl/engine.h>
#include "ssl_locl.h"
#define SSL_ENC_DES_IDX 0
@@ -172,9 +173,22 @@ static STACK_OF(SSL_COMP) *ssl_comp_methods=NULL;
#define SSL_MD_MD5_IDX 0
#define SSL_MD_SHA1_IDX 1
-#define SSL_MD_NUM_IDX 2
+#define SSL_MD_GOST94_IDX 2
+#define SSL_MD_GOST89MAC_IDX 3
+#define SSL_MD_NUM_IDX 4
static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]={
- NULL,NULL,
+ NULL,NULL,NULL,NULL
+ };
+/* PKEY_TYPE for GOST89MAC is known in advance, but, because
+ * implementation is engine-provided, we'll fill it only if
+ * corresponding EVP_PKEY_METHOD is found
+ */
+static int ssl_mac_pkey_id[SSL_MD_NUM_IDX]={
+ EVP_PKEY_HMAC,EVP_PKEY_HMAC,EVP_PKEY_HMAC,NID_undef
+ };
+
+static int ssl_mac_secret_size[SSL_MD_NUM_IDX]={
+ 0,0,0,0
};
#define CIPHER_ADD 1
@@ -266,6 +280,8 @@ static const SSL_CIPHER cipher_aliases[]={
{0,SSL_TXT_MD5,0, 0,0,0,SSL_MD5, 0,0,0,0,0},
{0,SSL_TXT_SHA1,0, 0,0,0,SSL_SHA1, 0,0,0,0,0},
{0,SSL_TXT_SHA,0, 0,0,0,SSL_SHA1, 0,0,0,0,0},
+ {0,SSL_TXT_GOST94,0, 0,0,0,SSL_GOST94, 0,0,0,0,0},
+ {0,SSL_TXT_GOST89MAC,0, 0,0,0,SSL_GOST89MAC, 0,0,0,0,0},
/* protocol version aliases */
{0,SSL_TXT_SSLV2,0, 0,0,0,0,SSL_SSLV2, 0,0,0,0},
@@ -315,11 +331,36 @@ void ssl_load_ciphers(void)
ssl_digest_methods[SSL_MD_MD5_IDX]=
EVP_get_digestbyname(SN_md5);
+ ssl_mac_secret_size[SSL_MD_MD5_IDX]=
+ EVP_MD_size(ssl_digest_methods[SSL_MD_MD5_IDX]);
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]);
+ 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]);
+ }
+ ssl_digest_methods[SSL_MD_GOST89MAC_IDX]=
+ EVP_get_digestbyname(SN_id_Gost28147_89_MAC);
+ {
+ const EVP_PKEY_ASN1_METHOD *ameth;
+ ENGINE *tmpeng = NULL;
+ int pkey_id;
+ ameth = EVP_PKEY_asn1_find_str(&tmpeng,"gost-mac",-1);
+ if (ameth)
+ {
+ EVP_PKEY_asn1_get0_info(&pkey_id, NULL,NULL,NULL,NULL,ameth);
+ ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]= pkey_id;
+ ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX]=32;
+ }
+ if (tmpeng) ENGINE_finish(tmpeng);
+ }
+ }
#ifndef OPENSSL_NO_COMP
static int sk_comp_cmp(const SSL_COMP * const *a,
@@ -374,7 +415,7 @@ static void load_builtin_compressions(void)
#endif
int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
- const EVP_MD **md, SSL_COMP **comp)
+ const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size,SSL_COMP **comp)
{
int i;
SSL_CIPHER *c;
@@ -463,16 +504,31 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
case SSL_SHA1:
i=SSL_MD_SHA1_IDX;
break;
+ case SSL_GOST94:
+ i = SSL_MD_GOST94_IDX;
+ break;
+ case SSL_GOST89MAC:
+ i = SSL_MD_GOST89MAC_IDX;
+ break;
default:
i= -1;
break;
}
if ((i < 0) || (i > SSL_MD_NUM_IDX))
- *md=NULL;
+ {
+ *md=NULL;
+ if (mac_pkey_type!=NULL) *mac_pkey_type = NID_undef;
+ if (mac_secret_size!=NULL) *mac_secret_size = 0;
+
+ }
else
+ {
*md=ssl_digest_methods[i];
+ if (mac_pkey_type!=NULL) *mac_pkey_type = ssl_mac_pkey_id[i];
+ if (mac_secret_size!=NULL) *mac_secret_size = ssl_mac_secret_size[i];
+ }
- if ((*enc != NULL) && (*md != NULL))
+ if ((*enc != NULL) && (*md != NULL) && (!mac_pkey_type||*mac_pkey_type != NID_undef))
return(1);
else
return(0);
@@ -567,6 +623,9 @@ static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, un
*mac |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0;
*mac |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0;
+ *mac |= (ssl_digest_methods[SSL_MD_GOST94_IDX] == NULL) ? SSL_GOST94:0;
+ *mac |= (ssl_digest_methods[SSL_MD_GOST89MAC_IDX] == NULL || ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]==NID_undef)? SSL_GOST89MAC:0;
+
}
static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method,
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index d73c7ca080..ab15575eec 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -225,6 +225,8 @@ int SSL_clear(SSL *s)
}
ssl_clear_cipher_ctx(s);
+ ssl_clear_hash_ctx(&s->read_hash);
+ ssl_clear_hash_ctx(&s->write_hash);
s->first_packet=0;
@@ -523,6 +525,8 @@ void SSL_free(SSL *s)
}
ssl_clear_cipher_ctx(s);
+ ssl_clear_hash_ctx(&s->read_hash);
+ ssl_clear_hash_ctx(&s->write_hash);
if (s->cert != NULL) ssl_cert_free(s->cert);
/* Free up if allocated */
@@ -2203,6 +2207,8 @@ void SSL_set_accept_state(SSL *s)
s->handshake_func=s->method->ssl_accept;
/* clear the current cipher */
ssl_clear_cipher_ctx(s);
+ ssl_clear_hash_ctx(&s->read_hash);
+ ssl_clear_hash_ctx(&s->write_hash);
}
void SSL_set_connect_state(SSL *s)
@@ -2213,6 +2219,8 @@ void SSL_set_connect_state(SSL *s)
s->handshake_func=s->method->ssl_connect;
/* clear the current cipher */
ssl_clear_cipher_ctx(s);
+ ssl_clear_hash_ctx(&s->read_hash);
+ ssl_clear_hash_ctx(&s->write_hash);
}
int ssl_undefined_function(SSL *s)
@@ -2836,7 +2844,25 @@ void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int con
SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
}
-
+/* Allocates new EVP_MD_CTX and sets pointer to it into given pointer
+ * vairable, freeing EVP_MD_CTX previously stored in that variable, if
+ * any. If EVP_MD pointer is passed, initializes ctx with this md
+ * Returns newly allocated ctx;
+ */
+
+EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash,const EVP_MD *md)
+{
+ ssl_clear_hash_ctx(hash);
+ *hash = EVP_MD_CTX_create();
+ if (md) EVP_DigestInit_ex(*hash,md,NULL);
+ return *hash;
+}
+void ssl_clear_hash_ctx(EVP_MD_CTX **hash)
+{
+
+ if (*hash) EVP_MD_CTX_destroy(*hash);
+ *hash=NULL;
+}
#if defined(_WINDLL) && defined(OPENSSL_SYS_WIN16)
#include "../crypto/bio/bss_file.c"
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 8488a6153f..004e21ddb8 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -320,7 +320,8 @@
/* Bits for algorithm_mac (symmetric authentication) */
#define SSL_MD5 0x00000001L
#define SSL_SHA1 0x00000002L
-
+#define SSL_GOST94 0x00000004L
+#define SSL_GOST89MAC 0x00000008L
/* Bits for algorithm_ssl (protocol version) */
#define SSL_SSLV2 0x00000001L
@@ -753,7 +754,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *meth,
const char *rule_str);
void ssl_update_cache(SSL *s, int mode);
int ssl_cipher_get_evp(const SSL_SESSION *s,const EVP_CIPHER **enc,
- const EVP_MD **md,SSL_COMP **comp);
+ const EVP_MD **md,int *mac_pkey_type,int *mac_secret_size, SSL_COMP **comp);
int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk);
int ssl_undefined_function(SSL *s);
int ssl_undefined_void_function(void);
@@ -984,5 +985,7 @@ int ssl_prepare_clienthello_tlsext(SSL *s);
int ssl_prepare_serverhello_tlsext(SSL *s);
int ssl_check_clienthello_tlsext(SSL *s);
int ssl_check_serverhello_tlsext(SSL *s);
+EVP_MD_CTX* ssl_replace_hash(EVP_MD_CTX **hash,const EVP_MD *md) ;
+void ssl_clear_hash_ctx(EVP_MD_CTX **hash);
#endif
#endif
diff --git a/ssl/ssl_txt.c b/ssl/ssl_txt.c
index f51e48b233..22f9a403af 100644
--- a/ssl/ssl_txt.c
+++ b/ssl/ssl_txt.c
@@ -188,7 +188,7 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
{
SSL_COMP *comp = NULL;
- ssl_cipher_get_evp(x,NULL,NULL,&comp);
+ ssl_cipher_get_evp(x,NULL,NULL,NULL,NULL,&comp);
if (comp == NULL)
{
if (BIO_printf(bp,"\n Compression: %d",x->compress_meth) <= 0) goto err;
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index 8398d271d6..7a4e2ce076 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -261,12 +261,17 @@ int tls1_change_cipher_state(SSL *s, int which)
const SSL_COMP *comp;
#endif
const EVP_MD *m;
+ int mac_type;
+ int *mac_secret_size;
+ EVP_MD_CTX *mac_ctx;
+ EVP_PKEY *mac_key;
int is_export,n,i,j,k,exp_label_len,cl;
int reuse_dd = 0;
is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
c=s->s3->tmp.new_sym_enc;
m=s->s3->tmp.new_hash;
+ mac_type = s->s3->tmp.new_mac_pkey_type;
#ifndef OPENSSL_NO_COMP
comp=s->s3->tmp.new_compression;
#endif
@@ -291,6 +296,11 @@ int tls1_change_cipher_state(SSL *s, int which)
if (which & SSL3_CC_READ)
{
+ if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
+ s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM;
+ else
+ s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM;
+
if (s->enc_read_ctx != NULL)
reuse_dd = 1;
else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
@@ -299,7 +309,7 @@ int tls1_change_cipher_state(SSL *s, int which)
/* make sure it's intialized in case we exit later with an error */
EVP_CIPHER_CTX_init(s->enc_read_ctx);
dd= s->enc_read_ctx;
- s->read_hash=m;
+ mac_ctx=ssl_replace_hash(&s->read_hash,NULL);
#ifndef OPENSSL_NO_COMP
if (s->expand != NULL)
{
@@ -325,9 +335,14 @@ int tls1_change_cipher_state(SSL *s, int which)
if (s->version != DTLS1_VERSION)
memset(&(s->s3->read_sequence[0]),0,8);
mac_secret= &(s->s3->read_mac_secret[0]);
+ mac_secret_size=&(s->s3->read_mac_secret_size);
}
else
{
+ if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
+ s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM;
+ else
+ s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM;
if (s->enc_write_ctx != NULL)
reuse_dd = 1;
else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
@@ -336,7 +351,7 @@ int tls1_change_cipher_state(SSL *s, int which)
/* make sure it's intialized in case we exit later with an error */
EVP_CIPHER_CTX_init(s->enc_write_ctx);
dd= s->enc_write_ctx;
- s->write_hash=m;
+ mac_ctx = ssl_replace_hash(&s->write_hash,NULL);
#ifndef OPENSSL_NO_COMP
if (s->compress != NULL)
{
@@ -357,13 +372,15 @@ int tls1_change_cipher_state(SSL *s, int which)
if (s->version != DTLS1_VERSION)
memset(&(s->s3->write_sequence[0]),0,8);
mac_secret= &(s->s3->write_mac_secret[0]);
+ mac_secret_size = &(s->s3->write_mac_secret_size);
}
if (reuse_dd)
EVP_CIPHER_CTX_cleanup(dd);
p=s->s3->tmp.key_block;
- i=EVP_MD_size(m);
+ i=*mac_secret_size=s->s3->tmp.new_mac_secret_size;
+
cl=EVP_CIPHER_key_length(c);
j=is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ?
cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl;
@@ -399,6 +416,10 @@ int tls1_change_cipher_state(SSL *s, int which)
}
memcpy(mac_secret,ms,i);
+ mac_key = EVP_PKEY_new_mac_key(mac_type, NULL,
+ mac_secret,*mac_secret_size);
+ EVP_DigestSignInit(mac_ctx,NULL,m,NULL,mac_key);
+ EVP_PKEY_free(mac_key);
#ifdef TLS_DEBUG
printf("which = %04X\nmac key=",which);
{ int z; for (z=0; z<i; z++) printf("%02X%c",ms[z],((z+1)%16)?' ':'\n'); }
@@ -477,6 +498,7 @@ int tls1_setup_key_block(SSL *s)
const EVP_MD *hash;
int num;
SSL_COMP *comp;
+ int mac_type= NID_undef,mac_secret_size=0;
#ifdef KSSL_DEBUG
printf ("tls1_setup_key_block()\n");
@@ -485,7 +507,7 @@ int tls1_setup_key_block(SSL *s)
if (s->s3->tmp.key_block_length != 0)
return(1);
- if (!ssl_cipher_get_evp(s->session,&c,&hash,&comp))
+ if (!ssl_cipher_get_evp(s->session,&c,&hash,&mac_type,&mac_secret_size,&comp))
{
SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
return(0);
@@ -493,8 +515,9 @@ int tls1_setup_key_block(SSL *s)
s->s3->tmp.new_sym_enc=c;
s->s3->tmp.new_hash=hash;
-
- num=EVP_CIPHER_key_length(c)+EVP_MD_size(hash)+EVP_CIPHER_iv_length(c);
+ s->s3->tmp.new_mac_pkey_type = mac_type;
+ s->s3->tmp.new_mac_secret_size = mac_secret_size;
+ num=EVP_CIPHER_key_length(c)+mac_secret_size+EVP_CIPHER_iv_length(c);
num*=2;
ssl3_cleanup_key_block(s);
@@ -559,8 +582,8 @@ int tls1_enc(SSL *s, int send)
if (send)
{
- if (s->write_hash != NULL)
- n=EVP_MD_size(s->write_hash);
+ if (EVP_MD_CTX_md(s->write_hash))
+ n=EVP_MD_CTX_size(s->write_hash);
ds=s->enc_write_ctx;
rec= &(s->s3->wrec);
if (s->enc_write_ctx == NULL)
@@ -570,8 +593,8 @@ int tls1_enc(SSL *s, int send)
}
else
{
- if (s->read_hash != NULL)
- n=EVP_MD_size(s->read_hash);
+ if (EVP_MD_CTX_md(s->read_hash))
+ n=EVP_MD_CTX_size(s->read_hash);
ds=s->enc_read_ctx;
rec= &(s->s3->rrec);
if (s->enc_read_ctx == NULL)
@@ -742,12 +765,12 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
{
SSL3_RECORD *rec;
unsigned char *mac_sec,*seq;
- const EVP_MD *hash;
- unsigned int md_size;
+ EVP_MD_CTX *hash;
+ size_t md_size;
int i;
- HMAC_CTX hmac;
+ 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));
if (send)
{
rec= &(ssl->s3->wrec);
@@ -763,7 +786,7 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
hash=ssl->read_hash;
}
- md_size=EVP_MD_size(hash);
+ md_size=EVP_MD_CTX_size(hash);
buf[0]=rec->type;
buf[1]=TLS1_VERSION_MAJOR;
@@ -772,14 +795,21 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
buf[4]=rec->length&0xff;
/* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */
- HMAC_CTX_init(&hmac);
- HMAC_Init_ex(&hmac,mac_sec,EVP_MD_size(hash),hash,NULL);
- HMAC_Update(&hmac,seq,8);
- HMAC_Update(&hmac,buf,5);
- HMAC_Update(&hmac,rec->input,rec->length);
- HMAC_Final(&hmac,md,&md_size);
- HMAC_CTX_cleanup(&hmac);
-
+ if (stream_mac)
+ {
+ mac_ctx = hash;
+ }
+ else
+ {
+ EVP_MD_CTX_copy(&hmac,hash);
+ mac_ctx = &hmac;
+ }
+ EVP_DigestSignUpdate(mac_ctx,seq,8);
+ EVP_DigestSignUpdate(mac_ctx,buf,5);
+ EVP_DigestSignUpdate(mac_ctx,rec->input,rec->length);
+ if (stream_mac) EVP_MD_CTX_copy(&hmac,hash);
+ EVP_DigestSignFinal(&hmac,md,&md_size);
+ EVP_MD_CTX_cleanup(&hmac);
#ifdef TLS_DEBUG
printf("sec=");
{unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",mac_sec[z]); printf("\n"); }
diff --git a/ssl/tls1.h b/ssl/tls1.h
index 05d74f5416..84ab246f14 100644
--- a/ssl/tls1.h
+++ b/ssl/tls1.h
@@ -404,6 +404,10 @@ SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG,0, (void *)arg)
#define TLS1_TXT_DHE_RSA_WITH_SEED_SHA "DHE-RSA-SEED-SHA"
#define TLS1_TXT_ADH_WITH_SEED_SHA "ADH-SEED-SHA"
+/* Flags for SSL_CIPHER.algorithm2 field */
+/* Stream MAC for GOST ciphersuites from cryptopro draft */
+#define TLS1_STREAM_MAC 0x04
+
#define TLS_CT_RSA_SIGN 1
#define TLS_CT_DSS_SIGN 2
#define TLS_CT_RSA_FIXED_DH 3