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

PR: 2259

Submitted By: Artem Chuprina <ran@cryptocom.ru>

Check return values of HMAC in tls_P_hash and tls1_generate_key_block.

Although the previous version could in theory crash that would only happen if a
digest call failed. The standard software methods can never fail and only one
ENGINE currently uses digests and it is not compiled in by default.
上级 acf635b9
...@@ -149,7 +149,7 @@ ...@@ -149,7 +149,7 @@
#endif #endif
/* seed1 through seed5 are virtually concatenated */ /* seed1 through seed5 are virtually concatenated */
static void tls1_P_hash(const EVP_MD *md, const unsigned char *sec, static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
int sec_len, int sec_len,
const void *seed1, int seed1_len, const void *seed1, int seed1_len,
const void *seed2, int seed2_len, const void *seed2, int seed2_len,
...@@ -164,55 +164,79 @@ static void tls1_P_hash(const EVP_MD *md, const unsigned char *sec, ...@@ -164,55 +164,79 @@ static void tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
HMAC_CTX ctx_tmp; HMAC_CTX ctx_tmp;
unsigned char A1[EVP_MAX_MD_SIZE]; unsigned char A1[EVP_MAX_MD_SIZE];
unsigned int A1_len; unsigned int A1_len;
int ret = 0;
chunk=EVP_MD_size(md); chunk=EVP_MD_size(md);
OPENSSL_assert(chunk >= 0); OPENSSL_assert(chunk >= 0);
HMAC_CTX_init(&ctx); HMAC_CTX_init(&ctx);
HMAC_CTX_init(&ctx_tmp); HMAC_CTX_init(&ctx_tmp);
HMAC_Init_ex(&ctx,sec,sec_len,md, NULL); if (!HMAC_Init_ex(&ctx,sec,sec_len,md, NULL))
HMAC_Init_ex(&ctx_tmp,sec,sec_len,md, NULL); goto err;
if (seed1 != NULL) HMAC_Update(&ctx,seed1,seed1_len); if (!HMAC_Init_ex(&ctx_tmp,sec,sec_len,md, NULL))
if (seed2 != NULL) HMAC_Update(&ctx,seed2,seed2_len); goto err;
if (seed3 != NULL) HMAC_Update(&ctx,seed3,seed3_len); if (seed1 != NULL && !HMAC_Update(&ctx,seed1,seed1_len))
if (seed4 != NULL) HMAC_Update(&ctx,seed4,seed4_len); goto err;
if (seed5 != NULL) HMAC_Update(&ctx,seed5,seed5_len); if (seed2 != NULL && !HMAC_Update(&ctx,seed2,seed2_len))
HMAC_Final(&ctx,A1,&A1_len); goto err;
if (seed3 != NULL && !HMAC_Update(&ctx,seed3,seed3_len))
goto err;
if (seed4 != NULL && !HMAC_Update(&ctx,seed4,seed4_len))
goto err;
if (seed5 != NULL && !HMAC_Update(&ctx,seed5,seed5_len))
goto err;
if (!HMAC_Final(&ctx,A1,&A1_len))
goto err;
n=0; n=0;
for (;;) for (;;)
{ {
HMAC_Init_ex(&ctx,NULL,0,NULL,NULL); /* re-init */ if (!HMAC_Init_ex(&ctx,NULL,0,NULL,NULL)) /* re-init */
HMAC_Init_ex(&ctx_tmp,NULL,0,NULL,NULL); /* re-init */ goto err;
HMAC_Update(&ctx,A1,A1_len); if (!HMAC_Init_ex(&ctx_tmp,NULL,0,NULL,NULL)) /* re-init */
HMAC_Update(&ctx_tmp,A1,A1_len); goto err;
if (seed1 != NULL) HMAC_Update(&ctx,seed1,seed1_len); if (!HMAC_Update(&ctx,A1,A1_len))
if (seed2 != NULL) HMAC_Update(&ctx,seed2,seed2_len); goto err;
if (seed3 != NULL) HMAC_Update(&ctx,seed3,seed3_len); if (!HMAC_Update(&ctx_tmp,A1,A1_len))
if (seed4 != NULL) HMAC_Update(&ctx,seed4,seed4_len); goto err;
if (seed5 != NULL) HMAC_Update(&ctx,seed5,seed5_len); if (seed1 != NULL && !HMAC_Update(&ctx,seed1,seed1_len))
goto err;
if (seed2 != NULL && !HMAC_Update(&ctx,seed2,seed2_len))
goto err;
if (seed3 != NULL && !HMAC_Update(&ctx,seed3,seed3_len))
goto err;
if (seed4 != NULL && !HMAC_Update(&ctx,seed4,seed4_len))
goto err;
if (seed5 != NULL && !HMAC_Update(&ctx,seed5,seed5_len))
goto err;
if (olen > chunk) if (olen > chunk)
{ {
HMAC_Final(&ctx,out,&j); if (!HMAC_Final(&ctx,out,&j))
goto err;
out+=j; out+=j;
olen-=j; olen-=j;
HMAC_Final(&ctx_tmp,A1,&A1_len); /* calc the next A1 value */ if (!HMAC_Final(&ctx_tmp,A1,&A1_len)) /* calc the next A1 value */
goto err;
} }
else /* last one */ else /* last one */
{ {
HMAC_Final(&ctx,A1,&A1_len); if (!HMAC_Final(&ctx,A1,&A1_len))
goto err;
memcpy(out,A1,olen); memcpy(out,A1,olen);
break; break;
} }
} }
ret = 1;
err:
HMAC_CTX_cleanup(&ctx); HMAC_CTX_cleanup(&ctx);
HMAC_CTX_cleanup(&ctx_tmp); HMAC_CTX_cleanup(&ctx_tmp);
OPENSSL_cleanse(A1,sizeof(A1)); OPENSSL_cleanse(A1,sizeof(A1));
return ret;
} }
/* seed1 through seed5 are virtually concatenated */ /* seed1 through seed5 are virtually concatenated */
static void tls1_PRF(long digest_mask, static int tls1_PRF(long digest_mask,
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,
...@@ -226,6 +250,7 @@ static void tls1_PRF(long digest_mask, ...@@ -226,6 +250,7 @@ static void tls1_PRF(long digest_mask,
const unsigned char *S1; const unsigned char *S1;
long m; long m;
const EVP_MD *md; const EVP_MD *md;
int ret = 0;
/* Count number of digests and partition sec evenly */ /* Count number of digests and partition sec evenly */
count=0; count=0;
...@@ -240,11 +265,12 @@ static void tls1_PRF(long digest_mask, ...@@ -240,11 +265,12 @@ static void tls1_PRF(long digest_mask,
if (!md) { if (!md) {
SSLerr(SSL_F_TLS1_PRF, SSLerr(SSL_F_TLS1_PRF,
SSL_R_UNSUPPORTED_DIGEST_TYPE); SSL_R_UNSUPPORTED_DIGEST_TYPE);
return; goto err;
} }
tls1_P_hash(md ,S1,len+(slen&1), if (!tls1_P_hash(md ,S1,len+(slen&1),
seed1,seed1_len,seed2,seed2_len,seed3,seed3_len,seed4,seed4_len,seed5,seed5_len, seed1,seed1_len,seed2,seed2_len,seed3,seed3_len,seed4,seed4_len,seed5,seed5_len,
out2,olen); out2,olen))
goto err;
S1+=len; S1+=len;
for (i=0; i<olen; i++) for (i=0; i<olen; i++)
{ {
...@@ -252,12 +278,15 @@ static void tls1_PRF(long digest_mask, ...@@ -252,12 +278,15 @@ static void tls1_PRF(long digest_mask,
} }
} }
} }
ret = 1;
err:
return ret;
} }
static void 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)
{ {
tls1_PRF(s->s3->tmp.new_cipher->algorithm2, int ret;
ret = tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
TLS_MD_KEY_EXPANSION_CONST,TLS_MD_KEY_EXPANSION_CONST_SIZE, TLS_MD_KEY_EXPANSION_CONST,TLS_MD_KEY_EXPANSION_CONST_SIZE,
s->s3->server_random,SSL3_RANDOM_SIZE, s->s3->server_random,SSL3_RANDOM_SIZE,
s->s3->client_random,SSL3_RANDOM_SIZE, s->s3->client_random,SSL3_RANDOM_SIZE,
...@@ -275,6 +304,7 @@ static void tls1_generate_key_block(SSL *s, unsigned char *km, ...@@ -275,6 +304,7 @@ static void tls1_generate_key_block(SSL *s, unsigned char *km,
} }
printf("\n"); } printf("\n"); }
#endif /* KSSL_DEBUG */ #endif /* KSSL_DEBUG */
return ret;
} }
int tls1_change_cipher_state(SSL *s, int which) int tls1_change_cipher_state(SSL *s, int which)
...@@ -462,22 +492,24 @@ printf("which = %04X\nmac key=",which); ...@@ -462,22 +492,24 @@ printf("which = %04X\nmac key=",which);
/* In here I set both the read and write key/iv to the /* In here I set both the read and write key/iv to the
* same value since only the correct one will be used :-). * same value since only the correct one will be used :-).
*/ */
tls1_PRF(s->s3->tmp.new_cipher->algorithm2, if (!tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
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,
NULL,0,NULL,0, NULL,0,NULL,0,
key,j,tmp1,tmp2,EVP_CIPHER_key_length(c)); key,j,tmp1,tmp2,EVP_CIPHER_key_length(c)))
goto err2;
key=tmp1; key=tmp1;
if (k > 0) if (k > 0)
{ {
tls1_PRF(s->s3->tmp.new_cipher->algorithm2, if (!tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
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,
NULL,0,NULL,0, NULL,0,NULL,0,
empty,0,iv1,iv2,k*2); empty,0,iv1,iv2,k*2))
goto err2;
if (client_write) if (client_write)
iv=iv1; iv=iv1;
else else
...@@ -519,12 +551,13 @@ err2: ...@@ -519,12 +551,13 @@ err2:
int tls1_setup_key_block(SSL *s) int tls1_setup_key_block(SSL *s)
{ {
unsigned char *p1,*p2; unsigned char *p1,*p2=NULL;
const EVP_CIPHER *c; const EVP_CIPHER *c;
const EVP_MD *hash; const EVP_MD *hash;
int num; int num;
SSL_COMP *comp; SSL_COMP *comp;
int mac_type= NID_undef,mac_secret_size=0; int mac_type= NID_undef,mac_secret_size=0;
int ret=0;
#ifdef KSSL_DEBUG #ifdef KSSL_DEBUG
printf ("tls1_setup_key_block()\n"); printf ("tls1_setup_key_block()\n");
...@@ -549,13 +582,19 @@ int tls1_setup_key_block(SSL *s) ...@@ -549,13 +582,19 @@ int tls1_setup_key_block(SSL *s)
ssl3_cleanup_key_block(s); ssl3_cleanup_key_block(s);
if ((p1=(unsigned char *)OPENSSL_malloc(num)) == NULL) if ((p1=(unsigned char *)OPENSSL_malloc(num)) == NULL)
{
SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE);
goto err; goto err;
if ((p2=(unsigned char *)OPENSSL_malloc(num)) == NULL) }
goto err;
s->s3->tmp.key_block_length=num; s->s3->tmp.key_block_length=num;
s->s3->tmp.key_block=p1; s->s3->tmp.key_block=p1;
if ((p2=(unsigned char *)OPENSSL_malloc(num)) == NULL)
{
SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE);
goto err;
}
#ifdef TLS_DEBUG #ifdef TLS_DEBUG
printf("client random\n"); printf("client random\n");
...@@ -565,9 +604,8 @@ printf("server random\n"); ...@@ -565,9 +604,8 @@ printf("server random\n");
printf("pre-master\n"); printf("pre-master\n");
{ int z; for (z=0; z<s->session->master_key_length; z++) printf("%02X%c",s->session->master_key[z],((z+1)%16)?' ':'\n'); } { int z; for (z=0; z<s->session->master_key_length; z++) printf("%02X%c",s->session->master_key[z],((z+1)%16)?' ':'\n'); }
#endif #endif
tls1_generate_key_block(s,p1,p2,num); if (!tls1_generate_key_block(s,p1,p2,num))
OPENSSL_cleanse(p2,num); goto err;
OPENSSL_free(p2);
#ifdef TLS_DEBUG #ifdef TLS_DEBUG
printf("\nkey block\n"); printf("\nkey block\n");
{ int z; for (z=0; z<num; z++) printf("%02X%c",p1[z],((z+1)%16)?' ':'\n'); } { int z; for (z=0; z<num; z++) printf("%02X%c",p1[z],((z+1)%16)?' ':'\n'); }
...@@ -592,10 +630,14 @@ printf("\nkey block\n"); ...@@ -592,10 +630,14 @@ printf("\nkey block\n");
} }
} }
return(1); ret = 1;
err: err:
SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE); if (p2)
return(0); {
OPENSSL_cleanse(p2,num);
OPENSSL_free(p2);
}
return(ret);
} }
int tls1_enc(SSL *s, int send) int tls1_enc(SSL *s, int send)
...@@ -849,10 +891,11 @@ int tls1_final_finish_mac(SSL *s, ...@@ -849,10 +891,11 @@ int tls1_final_finish_mac(SSL *s,
} }
} }
tls1_PRF(s->s3->tmp.new_cipher->algorithm2, if (!tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
str,slen, buf,(int)(q-buf), NULL,0, NULL,0, NULL,0, str,slen, buf,(int)(q-buf), 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))
err = 1;
EVP_MD_CTX_cleanup(&ctx); EVP_MD_CTX_cleanup(&ctx);
if (err) if (err)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册