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

PRF and handshake hash revision.

Change handshake hash array into a single digest context simplifying the
handhake hash code. Use EVP_md5_sha1() if needed for handshake hashes in
TLS 1.1 and earlier.

Simplify PRF code to also use a single digest and treat EVP_md5_sha1()
as a special case.

Modify algorithm2 field of ciphers to use a single index value for handshake
hash and PRF instead of a bitmap.
Reviewed-by: NMatt Caswell <matt@openssl.org>
上级 2a9b9654
...@@ -140,26 +140,6 @@ ...@@ -140,26 +140,6 @@
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/md5.h> #include <openssl/md5.h>
static const unsigned char ssl3_pad_1[48] = {
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
};
static const unsigned char ssl3_pad_2[48] = {
0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
};
static int ssl3_handshake_mac(SSL *s, int md_nid,
const char *sender, int len, unsigned char *p);
static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
{ {
EVP_MD_CTX m5; EVP_MD_CTX m5;
...@@ -488,69 +468,48 @@ void ssl3_init_finished_mac(SSL *s) ...@@ -488,69 +468,48 @@ void ssl3_init_finished_mac(SSL *s)
void ssl3_free_digest_list(SSL *s) void ssl3_free_digest_list(SSL *s)
{ {
int i;
BIO_free(s->s3->handshake_buffer); BIO_free(s->s3->handshake_buffer);
s->s3->handshake_buffer = NULL; s->s3->handshake_buffer = NULL;
if (!s->s3->handshake_dgst) EVP_MD_CTX_destroy(s->s3->handshake_dgst);
return;
for (i = 0; i < SSL_MAX_DIGEST; i++) {
if (s->s3->handshake_dgst[i])
EVP_MD_CTX_destroy(s->s3->handshake_dgst[i]);
}
OPENSSL_free(s->s3->handshake_dgst);
s->s3->handshake_dgst = NULL; s->s3->handshake_dgst = NULL;
} }
void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len) void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len)
{ {
if (s->s3->handshake_dgst == NULL) { if (s->s3->handshake_dgst == NULL)
BIO_write(s->s3->handshake_buffer, (void *)buf, len); BIO_write(s->s3->handshake_buffer, (void *)buf, len);
} else { else
int i; EVP_DigestUpdate(s->s3->handshake_dgst, buf, len);
for (i = 0; i < SSL_MAX_DIGEST; i++) {
if (s->s3->handshake_dgst[i] != NULL)
EVP_DigestUpdate(s->s3->handshake_dgst[i], buf, len);
}
}
} }
int ssl3_digest_cached_records(SSL *s, int keep) int ssl3_digest_cached_records(SSL *s, int keep)
{ {
int i;
long mask;
const EVP_MD *md; const EVP_MD *md;
long hdatalen; long hdatalen;
void *hdata; void *hdata;
if (s->s3->handshake_dgst == NULL) { if (s->s3->handshake_dgst == NULL) {
/* Allocate handshake_dgst array */
s->s3->handshake_dgst =
OPENSSL_malloc(sizeof(*s->s3->handshake_dgst) * SSL_MAX_DIGEST);
if (s->s3->handshake_dgst == NULL) {
SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_MALLOC_FAILURE);
return 0;
}
hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
if (hdatalen <= 0) { if (hdatalen <= 0) {
SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, SSL_R_BAD_HANDSHAKE_LENGTH); SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, SSL_R_BAD_HANDSHAKE_LENGTH);
return 0; return 0;
} }
/* Loop through bits of algorithm2 field and create MD_CTX-es */ s->s3->handshake_dgst = EVP_MD_CTX_create();
for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++) { if (s->s3->handshake_dgst == NULL) {
if ((mask & ssl_get_algorithm2(s)) && md) { SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_MALLOC_FAILURE);
s->s3->handshake_dgst[i] = EVP_MD_CTX_create(); return 0;
if (EVP_MD_nid(md) == NID_md5) {
EVP_MD_CTX_set_flags(s->s3->handshake_dgst[i],
EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
}
EVP_DigestInit_ex(s->s3->handshake_dgst[i], md, NULL);
EVP_DigestUpdate(s->s3->handshake_dgst[i], hdata, hdatalen);
} else {
s->s3->handshake_dgst[i] = NULL;
}
} }
md = ssl_handshake_md(s);
if (md == NULL) {
SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_INTERNAL_ERROR);
return 0;
}
EVP_DigestInit_ex(s->s3->handshake_dgst, md, NULL);
EVP_DigestUpdate(s->s3->handshake_dgst, hdata, hdatalen);
} }
if (keep == 0) { if (keep == 0) {
BIO_free(s->s3->handshake_buffer); BIO_free(s->s3->handshake_buffer);
...@@ -560,77 +519,40 @@ int ssl3_digest_cached_records(SSL *s, int keep) ...@@ -560,77 +519,40 @@ int ssl3_digest_cached_records(SSL *s, int keep)
return 1; return 1;
} }
int ssl3_final_finish_mac(SSL *s, int ssl3_final_finish_mac(SSL *s, const char *sender, int len, unsigned char *p)
const char *sender, int len, unsigned char *p)
{ {
int ret, sha1len; int ret;
ret = ssl3_handshake_mac(s, NID_md5, sender, len, p); EVP_MD_CTX ctx;
if (ret == 0)
return 0;
p += ret;
sha1len = ssl3_handshake_mac(s, NID_sha1, sender, len, p);
if (sha1len == 0)
return 0;
ret += sha1len;
return (ret);
}
static int ssl3_handshake_mac(SSL *s, int md_nid,
const char *sender, int len, unsigned char *p)
{
unsigned int ret;
int npad, n;
unsigned int i;
unsigned char md_buf[EVP_MAX_MD_SIZE];
EVP_MD_CTX ctx, *d = NULL;
if (!ssl3_digest_cached_records(s, 0)) if (!ssl3_digest_cached_records(s, 0))
return 0; return 0;
/* if (EVP_MD_CTX_type(s->s3->handshake_dgst) != NID_md5_sha1) {
* Search for digest of specified type in the handshake_dgst array
*/
for (i = 0; i < SSL_MAX_DIGEST; i++) {
if (s->s3->handshake_dgst[i]
&& EVP_MD_CTX_type(s->s3->handshake_dgst[i]) == md_nid) {
d = s->s3->handshake_dgst[i];
break;
}
}
if (!d) {
SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, SSL_R_NO_REQUIRED_DIGEST); SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, SSL_R_NO_REQUIRED_DIGEST);
return 0; return 0;
} }
EVP_MD_CTX_init(&ctx); EVP_MD_CTX_init(&ctx);
EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); EVP_MD_CTX_copy_ex(&ctx, s->s3->handshake_dgst);
EVP_MD_CTX_copy_ex(&ctx, d);
n = EVP_MD_CTX_size(&ctx); ret = EVP_MD_CTX_size(&ctx);
if (n < 0) if (ret < 0) {
EVP_MD_CTX_cleanup(&ctx);
return 0; return 0;
}
npad = (48 / n) * n;
if ((sender != NULL && EVP_DigestUpdate(&ctx, sender, len) <= 0) if ((sender != NULL && EVP_DigestUpdate(&ctx, sender, len) <= 0)
|| EVP_DigestUpdate(&ctx, s->session->master_key, || EVP_MD_CTX_ctrl(&ctx, EVP_CTRL_SSL3_MASTER_SECRET,
s->session->master_key_length) <= 0 s->session->master_key_length,
|| EVP_DigestUpdate(&ctx, ssl3_pad_1, npad) <= 0 s->session->master_key) <= 0
|| EVP_DigestFinal_ex(&ctx, md_buf, &i) <= 0 || EVP_DigestFinal_ex(&ctx, p, NULL) <= 0) {
|| EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL) <= 0
|| EVP_DigestUpdate(&ctx, s->session->master_key,
s->session->master_key_length) <= 0
|| EVP_DigestUpdate(&ctx, ssl3_pad_2, npad) <= 0
|| EVP_DigestUpdate(&ctx, md_buf, i) <= 0
|| EVP_DigestFinal_ex(&ctx, p, &ret) <= 0) {
SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, ERR_R_INTERNAL_ERROR); SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, ERR_R_INTERNAL_ERROR);
ret = 0; ret = 0;
} }
EVP_MD_CTX_cleanup(&ctx); EVP_MD_CTX_cleanup(&ctx);
return ((int)ret); return ret;
} }
int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
......
...@@ -110,6 +110,9 @@ int SSL_library_init(void) ...@@ -110,6 +110,9 @@ int SSL_library_init(void)
#ifndef OPENSSL_NO_MD5 #ifndef OPENSSL_NO_MD5
EVP_add_digest(EVP_md5()); EVP_add_digest(EVP_md5());
EVP_add_digest_alias(SN_md5, "ssl3-md5"); EVP_add_digest_alias(SN_md5, "ssl3-md5");
# ifndef OPENSSL_NO_SHA
EVP_add_digest(EVP_md5_sha1());
# endif
#endif #endif
EVP_add_digest(EVP_sha1()); /* RSA with sha1 */ EVP_add_digest(EVP_sha1()); /* RSA with sha1 */
EVP_add_digest_alias(SN_sha1, "ssl3-sha1"); EVP_add_digest_alias(SN_sha1, "ssl3-sha1");
......
...@@ -212,15 +212,6 @@ static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX] = { ...@@ -212,15 +212,6 @@ static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX] = {
static STACK_OF(SSL_COMP) *ssl_comp_methods = NULL; static STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
#define SSL_MD_MD5_IDX 0
#define SSL_MD_SHA1_IDX 1
#define SSL_MD_GOST94_IDX 2
#define SSL_MD_GOST89MAC_IDX 3
#define SSL_MD_SHA256_IDX 4
#define SSL_MD_SHA384_IDX 5
#define SSL_MD_GOST12_256_IDX 6
#define SSL_MD_GOST89MAC12_IDX 7
#define SSL_MD_GOST12_512_IDX 8
/* /*
* Constant SSL_MAX_DIGEST equal to size of digests array should be defined * Constant SSL_MAX_DIGEST equal to size of digests array should be defined
* in the ssl_locl.h * in the ssl_locl.h
...@@ -238,11 +229,12 @@ static const ssl_cipher_table ssl_cipher_table_mac[SSL_MD_NUM_IDX] = { ...@@ -238,11 +229,12 @@ static const ssl_cipher_table ssl_cipher_table_mac[SSL_MD_NUM_IDX] = {
{SSL_SHA384, NID_sha384}, /* SSL_MD_SHA384_IDX 5 */ {SSL_SHA384, NID_sha384}, /* SSL_MD_SHA384_IDX 5 */
{SSL_GOST12_256, NID_id_GostR3411_2012_256}, /* SSL_MD_GOST12_256_IDX 6 */ {SSL_GOST12_256, NID_id_GostR3411_2012_256}, /* SSL_MD_GOST12_256_IDX 6 */
{SSL_GOST89MAC12, NID_gost_mac_12}, /* SSL_MD_GOST89MAC12_IDX 7 */ {SSL_GOST89MAC12, NID_gost_mac_12}, /* SSL_MD_GOST89MAC12_IDX 7 */
{SSL_GOST12_512, NID_id_GostR3411_2012_512} /* SSL_MD_GOST12_512_IDX 8 */ {SSL_GOST12_512, NID_id_GostR3411_2012_512}, /* SSL_MD_GOST12_512_IDX 8 */
{0, NID_md5_sha1} /* SSL_MD_MD5_SHA1_IDX 9 */
}; };
static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX] = { static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
}; };
/* Utility function for table lookup */ /* Utility function for table lookup */
...@@ -275,14 +267,7 @@ static int ssl_mac_pkey_id[SSL_MD_NUM_IDX] = { ...@@ -275,14 +267,7 @@ static int ssl_mac_pkey_id[SSL_MD_NUM_IDX] = {
}; };
static int ssl_mac_secret_size[SSL_MD_NUM_IDX] = { static int ssl_mac_secret_size[SSL_MD_NUM_IDX] = {
0, 0, 0, 0, 0, 0, 0, 0, 0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static const int ssl_handshake_digest_flag[SSL_MD_NUM_IDX] = {
SSL_HANDSHAKE_MAC_MD5, SSL_HANDSHAKE_MAC_SHA,
SSL_HANDSHAKE_MAC_GOST94, 0, SSL_HANDSHAKE_MAC_SHA256,
SSL_HANDSHAKE_MAC_SHA384, SSL_HANDSHAKE_MAC_GOST12_256, 0,
SSL_HANDSHAKE_MAC_GOST12_512,
}; };
#define CIPHER_ADD 1 #define CIPHER_ADD 1
...@@ -727,17 +712,22 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, ...@@ -727,17 +712,22 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
return (0); return (0);
} }
int ssl_get_handshake_digest(int idx, long *mask, const EVP_MD **md) static const EVP_MD *ssl_cipher_table_idx(int idx)
{ {
if (idx < 0 || idx >= SSL_MD_NUM_IDX) { idx &= SSL_HANDSHAKE_MAC_MASK;
return 0; if (idx < 0 || idx >= SSL_MD_NUM_IDX)
} return NULL;
*mask = ssl_handshake_digest_flag[idx]; return ssl_digest_methods[idx];
if (*mask) }
*md = ssl_digest_methods[idx];
else const EVP_MD *ssl_handshake_md(SSL *s)
*md = NULL; {
return 1; return ssl_cipher_table_idx(ssl_get_algorithm2(s));
}
const EVP_MD *ssl_prf_md(SSL *s)
{
return ssl_cipher_table_idx(ssl_get_algorithm2(s) >> TLS1_PRF_DGST_SHIFT);
} }
#define ITEM_SEP(a) \ #define ITEM_SEP(a) \
......
...@@ -3335,27 +3335,17 @@ void ssl_clear_hash_ctx(EVP_MD_CTX **hash) ...@@ -3335,27 +3335,17 @@ void ssl_clear_hash_ctx(EVP_MD_CTX **hash)
/* Retrieve handshake hashes */ /* Retrieve handshake hashes */
int ssl_handshake_hash(SSL *s, unsigned char *out, int outlen) int ssl_handshake_hash(SSL *s, unsigned char *out, int outlen)
{ {
unsigned char *p = out;
int idx, ret = 0;
long mask;
EVP_MD_CTX ctx; EVP_MD_CTX ctx;
const EVP_MD *md; EVP_MD_CTX *hdgst = s->s3->handshake_dgst;
int ret = EVP_MD_CTX_size(hdgst);
EVP_MD_CTX_init(&ctx); EVP_MD_CTX_init(&ctx);
for (idx = 0; ssl_get_handshake_digest(idx, &mask, &md); idx++) { if (ret < 0 || ret > outlen) {
if (mask & ssl_get_algorithm2(s)) { ret = 0;
int hashsize = EVP_MD_size(md); goto err;
EVP_MD_CTX *hdgst = s->s3->handshake_dgst[idx];
if (!hdgst || hashsize < 0 || hashsize > outlen)
goto err;
if (!EVP_MD_CTX_copy_ex(&ctx, hdgst))
goto err;
if (!EVP_DigestFinal_ex(&ctx, p, NULL))
goto err;
p += hashsize;
outlen -= hashsize;
}
} }
ret = p - out; if (!EVP_MD_CTX_copy_ex(&ctx, hdgst)
|| EVP_DigestFinal_ex(&ctx, out, NULL) <= 0)
ret = 0;
err: err:
EVP_MD_CTX_cleanup(&ctx); EVP_MD_CTX_cleanup(&ctx);
return ret; return ret;
......
...@@ -391,38 +391,50 @@ ...@@ -391,38 +391,50 @@
# define SSL_TLSV1 0x00000004U # define SSL_TLSV1 0x00000004U
# define SSL_TLSV1_2 0x00000008U # define SSL_TLSV1_2 0x00000008U
/* Bits for algorithm2 (handshake digests and other extra flags) */
# define SSL_HANDSHAKE_MAC_MD5 0x10
# define SSL_HANDSHAKE_MAC_SHA 0x20
# define SSL_HANDSHAKE_MAC_GOST94 0x40
# define SSL_HANDSHAKE_MAC_SHA256 0x80
# define SSL_HANDSHAKE_MAC_SHA384 0x100
# define SSL_HANDSHAKE_MAC_GOST12_256 0x200
# define SSL_HANDSHAKE_MAC_GOST12_512 0x400
# define SSL_HANDSHAKE_MAC_DEFAULT (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA)
/* /*
* When adding new digest in the ssl_ciph.c and increment SSL_MD_NUM_IDX make * When adding new digest in the ssl_ciph.c and increment SSL_MD_NUM_IDX make
* sure to update this constant too * sure to update this constant too
*/ */
# define SSL_MAX_DIGEST 9
# define SSL_MD_MD5_IDX 0
# define TLS1_PRF_DGST_SHIFT 10 # define SSL_MD_SHA1_IDX 1
# define TLS1_PRF_MD5 (SSL_HANDSHAKE_MAC_MD5 << TLS1_PRF_DGST_SHIFT) # define SSL_MD_GOST94_IDX 2
# define TLS1_PRF_SHA1 (SSL_HANDSHAKE_MAC_SHA << TLS1_PRF_DGST_SHIFT) # define SSL_MD_GOST89MAC_IDX 3
# define TLS1_PRF_SHA256 (SSL_HANDSHAKE_MAC_SHA256 << TLS1_PRF_DGST_SHIFT) # define SSL_MD_SHA256_IDX 4
# define TLS1_PRF_SHA384 (SSL_HANDSHAKE_MAC_SHA384 << TLS1_PRF_DGST_SHIFT) # define SSL_MD_SHA384_IDX 5
# define TLS1_PRF_GOST94 (SSL_HANDSHAKE_MAC_GOST94 << TLS1_PRF_DGST_SHIFT) # define SSL_MD_GOST12_256_IDX 6
# define TLS1_PRF_GOST12_256 (SSL_HANDSHAKE_MAC_GOST12_256 << TLS1_PRF_DGST_SHIFT) # define SSL_MD_GOST89MAC12_IDX 7
# define TLS1_PRF_GOST12_512 (SSL_HANDSHAKE_MAC_GOST12_512 << TLS1_PRF_DGST_SHIFT) # define SSL_MD_GOST12_512_IDX 8
# define TLS1_PRF (TLS1_PRF_MD5 | TLS1_PRF_SHA1) # define SSL_MD_MD5_SHA1_IDX 9
# define SSL_MAX_DIGEST 10
/* Bits for algorithm2 (handshake digests and other extra flags) */
/* Bits 0-7 are handshake MAC */
# define SSL_HANDSHAKE_MAC_MASK 0xFF
# define SSL_HANDSHAKE_MAC_MD5_SHA1 SSL_MD_MD5_SHA1_IDX
# define SSL_HANDSHAKE_MAC_SHA256 SSL_MD_SHA256_IDX
# define SSL_HANDSHAKE_MAC_SHA384 SSL_MD_SHA384_IDX
# define SSL_HANDSHAKE_MAC_GOST94 SSL_MD_GOST94_IDX
# define SSL_HANDSHAKE_MAC_GOST12_256 SSL_MD_GOST12_256_IDX
# define SSL_HANDSHAKE_MAC_GOST12_512 SSL_MD_GOST12_512_IDX
# define SSL_HANDSHAKE_MAC_DEFAULT SSL_HANDSHAKE_MAC_MD5_SHA1
/* Bits 8-15 bits are PRF */
# define TLS1_PRF_DGST_SHIFT 8
# define TLS1_PRF_SHA1_MD5 (SSL_MD_MD5_SHA1_IDX << TLS1_PRF_DGST_SHIFT)
# define TLS1_PRF_SHA256 (SSL_MD_SHA256_IDX << TLS1_PRF_DGST_SHIFT)
# define TLS1_PRF_SHA384 (SSL_MD_SHA384_IDX << TLS1_PRF_DGST_SHIFT)
# define TLS1_PRF_GOST94 (SSL_MD_GOST94_IDX << TLS1_PRF_DGST_SHIFT)
# define TLS1_PRF_GOST12_256 (SSL_MD_GOST12_256_IDX << TLS1_PRF_DGST_SHIFT)
# define TLS1_PRF_GOST12_512 (SSL_MD_GOST12_512_IDX << TLS1_PRF_DGST_SHIFT)
# define TLS1_PRF (SSL_MD_MD5_SHA1_IDX << TLS1_PRF_DGST_SHIFT)
/* /*
* Stream MAC for GOST ciphersuites from cryptopro draft (currently this also * Stream MAC for GOST ciphersuites from cryptopro draft (currently this also
* goes into algorithm2) * goes into algorithm2)
*/ */
# define TLS1_STREAM_MAC 0x04 # define TLS1_STREAM_MAC 0x10000
/* /*
* Export and cipher strength information. For each cipher we have to decide * Export and cipher strength information. For each cipher we have to decide
...@@ -1239,10 +1251,10 @@ typedef struct ssl3_state_st { ...@@ -1239,10 +1251,10 @@ typedef struct ssl3_state_st {
/* used during startup, digest all incoming/outgoing packets */ /* used during startup, digest all incoming/outgoing packets */
BIO *handshake_buffer; BIO *handshake_buffer;
/* /*
* When set of handshake digests is determined, buffer is hashed and * When handshake digest is determined, buffer is hashed and
* freed and MD_CTX-es for all required digests are stored in this array * freed and MD_CTX for the required digest is stored here.
*/ */
EVP_MD_CTX **handshake_dgst; EVP_MD_CTX *handshake_dgst;
/* /*
* Set whenever an expected ChangeCipherSpec message is processed. * Set whenever an expected ChangeCipherSpec message is processed.
* Unset when the peer's Finished message is received. * Unset when the peer's Finished message is received.
...@@ -1890,7 +1902,6 @@ void ssl_update_cache(SSL *s, int mode); ...@@ -1890,7 +1902,6 @@ void ssl_update_cache(SSL *s, int mode);
__owur int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, __owur int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
const EVP_MD **md, int *mac_pkey_type, const EVP_MD **md, int *mac_pkey_type,
int *mac_secret_size, SSL_COMP **comp, int use_etm); int *mac_secret_size, SSL_COMP **comp, int use_etm);
__owur int ssl_get_handshake_digest(int i, long *mask, const EVP_MD **md);
__owur int ssl_cipher_get_cert_index(const SSL_CIPHER *c); __owur int ssl_cipher_get_cert_index(const SSL_CIPHER *c);
__owur const SSL_CIPHER *ssl_get_cipher_by_char(SSL *ssl, const unsigned char *ptr); __owur const SSL_CIPHER *ssl_get_cipher_by_char(SSL *ssl, const unsigned char *ptr);
__owur int ssl_cert_set0_chain(SSL *s, SSL_CTX *ctx, STACK_OF(X509) *chain); __owur int ssl_cert_set0_chain(SSL *s, SSL_CTX *ctx, STACK_OF(X509) *chain);
...@@ -2128,6 +2139,8 @@ __owur int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, ...@@ -2128,6 +2139,8 @@ __owur int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len,
__owur int ssl_parse_serverhello_use_srtp_ext(SSL *s, PACKET *pkt, int *al); __owur int ssl_parse_serverhello_use_srtp_ext(SSL *s, PACKET *pkt, int *al);
__owur int ssl_handshake_hash(SSL *s, unsigned char *out, int outlen); __owur int ssl_handshake_hash(SSL *s, unsigned char *out, int outlen);
__owur const EVP_MD *ssl_handshake_md(SSL *s);
__owur const EVP_MD *ssl_prf_md(SSL *s);
/* s3_cbc.c */ /* s3_cbc.c */
__owur char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx); __owur char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx);
......
...@@ -236,7 +236,7 @@ static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec, ...@@ -236,7 +236,7 @@ static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
} }
/* seed1 through seed5 are virtually concatenated */ /* seed1 through seed5 are virtually concatenated */
static int tls1_PRF(long digest_mask, static int tls1_PRF(SSL *s,
const void *seed1, int seed1_len, const void *seed1, int seed1_len,
const void *seed2, int seed2_len, const void *seed2, int seed2_len,
const void *seed3, int seed3_len, const void *seed3, int seed3_len,
...@@ -245,55 +245,44 @@ static int tls1_PRF(long digest_mask, ...@@ -245,55 +245,44 @@ static int tls1_PRF(long digest_mask,
const unsigned char *sec, int slen, const unsigned char *sec, int slen,
unsigned char *out1, unsigned char *out2, int olen) unsigned char *out1, unsigned char *out2, int olen)
{ {
int len, i, idx, count; const EVP_MD *md = ssl_prf_md(s);
const unsigned char *S1;
long m;
const EVP_MD *md;
int ret = 0;
/* Count number of digests and partition sec evenly */ if (md == NULL) {
count = 0;
for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) {
if ((m << TLS1_PRF_DGST_SHIFT) & digest_mask)
count++;
}
if (!count) {
/* Should never happen */ /* Should never happen */
SSLerr(SSL_F_TLS1_PRF, ERR_R_INTERNAL_ERROR); SSLerr(SSL_F_TLS1_PRF, ERR_R_INTERNAL_ERROR);
goto err; return 0;
} }
len = slen / count; if (EVP_MD_type(md) == NID_md5_sha1) {
if (count == 1) int i;
slen = 0; if (!tls1_P_hash(EVP_md5(), sec, slen/2 + (slen & 1),
S1 = sec; seed1, seed1_len, seed2, seed2_len, seed3,
memset(out1, 0, olen); seed3_len, seed4, seed4_len, seed5, seed5_len,
for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) { out1, olen))
if ((m << TLS1_PRF_DGST_SHIFT) & digest_mask) { return 0;
if (!md) { if (!tls1_P_hash(EVP_sha1(), sec + slen/2, slen/2 + (slen & 1),
SSLerr(SSL_F_TLS1_PRF, SSL_R_UNSUPPORTED_DIGEST_TYPE); seed1, seed1_len, seed2, seed2_len, seed3,
goto err; seed3_len, seed4, seed4_len, seed5, seed5_len,
} out2, olen))
if (!tls1_P_hash(md, S1, len + (slen & 1), return 0;
seed1, seed1_len, seed2, seed2_len, seed3, for (i = 0; i < olen; i++)
seed3_len, seed4, seed4_len, seed5, seed5_len, out1[i] ^= out2[i];
out2, olen)) return 1;
goto err;
S1 += len;
for (i = 0; i < olen; i++) {
out1[i] ^= out2[i];
}
}
} }
ret = 1; memset(out2, 0, olen);
err: if (!tls1_P_hash(md, sec, slen,
return ret; seed1, seed1_len, seed2, seed2_len, seed3,
seed3_len, seed4, seed4_len, seed5, seed5_len,
out1, olen))
return 0;
return 1;
} }
static int tls1_generate_key_block(SSL *s, unsigned char *km, static int tls1_generate_key_block(SSL *s, unsigned char *km,
unsigned char *tmp, int num) unsigned char *tmp, int num)
{ {
int ret; int ret;
ret = tls1_PRF(ssl_get_algorithm2(s), ret = tls1_PRF(s,
TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST,
TLS_MD_KEY_EXPANSION_CONST_SIZE, s->s3->server_random, TLS_MD_KEY_EXPANSION_CONST_SIZE, s->s3->server_random,
SSL3_RANDOM_SIZE, s->s3->client_random, SSL3_RANDOM_SIZE, SSL3_RANDOM_SIZE, s->s3->client_random, SSL3_RANDOM_SIZE,
...@@ -489,7 +478,7 @@ int tls1_change_cipher_state(SSL *s, int which) ...@@ -489,7 +478,7 @@ int tls1_change_cipher_state(SSL *s, int which)
* In here I set both the read and write key/iv to the same value * In here I set both the read and write key/iv to the same value
* since only the correct one will be used :-). * since only the correct one will be used :-).
*/ */
if (!tls1_PRF(ssl_get_algorithm2(s), if (!tls1_PRF(s,
exp_label, exp_label_len, exp_label, exp_label_len,
s->s3->client_random, SSL3_RANDOM_SIZE, s->s3->client_random, SSL3_RANDOM_SIZE,
s->s3->server_random, SSL3_RANDOM_SIZE, s->s3->server_random, SSL3_RANDOM_SIZE,
...@@ -499,7 +488,7 @@ int tls1_change_cipher_state(SSL *s, int which) ...@@ -499,7 +488,7 @@ int tls1_change_cipher_state(SSL *s, int which)
key = tmp1; key = tmp1;
if (k > 0) { if (k > 0) {
if (!tls1_PRF(ssl_get_algorithm2(s), if (!tls1_PRF(s,
TLS_MD_IV_BLOCK_CONST, TLS_MD_IV_BLOCK_CONST_SIZE, TLS_MD_IV_BLOCK_CONST, TLS_MD_IV_BLOCK_CONST_SIZE,
s->s3->client_random, SSL3_RANDOM_SIZE, s->s3->client_random, SSL3_RANDOM_SIZE,
s->s3->server_random, SSL3_RANDOM_SIZE, s->s3->server_random, SSL3_RANDOM_SIZE,
...@@ -702,7 +691,7 @@ int tls1_final_finish_mac(SSL *s, const char *str, int slen, ...@@ -702,7 +691,7 @@ int tls1_final_finish_mac(SSL *s, const char *str, int slen,
unsigned char *out) unsigned char *out)
{ {
int hashlen; int hashlen;
unsigned char hash[2 * EVP_MAX_MD_SIZE]; unsigned char hash[EVP_MAX_MD_SIZE];
unsigned char buf2[12]; unsigned char buf2[12];
if (!ssl3_digest_cached_records(s, 0)) if (!ssl3_digest_cached_records(s, 0))
...@@ -713,7 +702,7 @@ int tls1_final_finish_mac(SSL *s, const char *str, int slen, ...@@ -713,7 +702,7 @@ int tls1_final_finish_mac(SSL *s, const char *str, int slen,
if (hashlen == 0) if (hashlen == 0)
return 0; return 0;
if (!tls1_PRF(ssl_get_algorithm2(s), if (!tls1_PRF(s,
str, slen, hash, hashlen, NULL, 0, NULL, 0, NULL, 0, str, slen, hash, hashlen, NULL, 0, NULL, 0, NULL, 0,
s->session->master_key, s->session->master_key_length, s->session->master_key, s->session->master_key_length,
out, buf2, sizeof buf2)) out, buf2, sizeof buf2))
...@@ -743,7 +732,7 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, ...@@ -743,7 +732,7 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
fprintf(stderr, "Handshake hashes:\n"); fprintf(stderr, "Handshake hashes:\n");
BIO_dump_fp(stderr, (char *)hash, hashlen); BIO_dump_fp(stderr, (char *)hash, hashlen);
#endif #endif
tls1_PRF(ssl_get_algorithm2(s), tls1_PRF(s,
TLS_MD_EXTENDED_MASTER_SECRET_CONST, TLS_MD_EXTENDED_MASTER_SECRET_CONST,
TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE, TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE,
hash, hashlen, hash, hashlen,
...@@ -752,7 +741,7 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, ...@@ -752,7 +741,7 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
NULL, 0, p, len, s->session->master_key, buff, sizeof buff); NULL, 0, p, len, s->session->master_key, buff, sizeof buff);
OPENSSL_cleanse(hash, hashlen); OPENSSL_cleanse(hash, hashlen);
} else { } else {
tls1_PRF(ssl_get_algorithm2(s), tls1_PRF(s,
TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST,
TLS_MD_MASTER_SECRET_CONST_SIZE, TLS_MD_MASTER_SECRET_CONST_SIZE,
s->s3->client_random, SSL3_RANDOM_SIZE, s->s3->client_random, SSL3_RANDOM_SIZE,
...@@ -858,7 +847,7 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, ...@@ -858,7 +847,7 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0)
goto err1; goto err1;
rv = tls1_PRF(ssl_get_algorithm2(s), rv = tls1_PRF(s,
val, vallen, val, vallen,
NULL, 0, NULL, 0,
NULL, 0, NULL, 0,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册