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.
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)
}
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)
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)
{
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
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);
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 *)
/* 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);
}
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];
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)
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);
/* 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)
/* 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)
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);
EVP_MD_CTX_init(&ctx);
EVP_MD_CTX_copy_ex(&ctx,in_ctx);
-
n=EVP_MD_CTX_size(&ctx);
npad=(48/n)*n;
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;
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);
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);
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 */
/* 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)
{
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)
#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"
#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
/* 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
#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
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];
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
#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
#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
{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},
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,
#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;
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);
*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,
}
ssl_clear_cipher_ctx(s);
+ ssl_clear_hash_ctx(&s->read_hash);
+ ssl_clear_hash_ctx(&s->write_hash);
s->first_packet=0;
}
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 */
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)
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)
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"
/* 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
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);
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
{
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;
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
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)
/* 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)
{
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)
/* 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)
{
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;
}
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'); }
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");
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);
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);
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)
}
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)
{
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);
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;
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"); }
#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