提交 b948e2c5 编写于 作者: D Dr. Stephen Henson

Update ssl library to support EVP_PKEY MAC API. Include generic MAC support.

上级 18096abb
......@@ -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.
......
......@@ -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)
......
......@@ -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
......
......@@ -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);
......
......@@ -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);
......
......@@ -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)
......
......@@ -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);
......
......@@ -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);
......
......@@ -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 */
......
......@@ -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)
......
......@@ -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
......
......@@ -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
......
......@@ -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,
......
......@@ -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"
......
......@@ -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
......@@ -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;
......
......@@ -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"); }
......
......@@ -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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册