提交 7c770d57 编写于 作者: B Ben Laurie 提交者: Dr. Stephen Henson

Add and use a constant-time memcmp.

This change adds CRYPTO_memcmp, which compares two vectors of bytes in
an amount of time that's independent of their contents. It also changes
several MAC compares in the code to use this over the standard memcmp,
which may leak information about the size of a matching prefix.
(cherry picked from commit 2ee798880a246d648ecddadc5b91367bee4a5d98)
上级 ea34a583
......@@ -397,3 +397,16 @@ void OpenSSLDie(const char *file,int line,const char *assertion)
#ifndef OPENSSL_FIPSCANISTER
void *OPENSSL_stderr(void) { return stderr; }
#endif
int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len)
{
size_t i;
const unsigned char *a = in_a;
const unsigned char *b = in_b;
unsigned char x = 0;
for (i = 0; i < len; i++)
x |= a[i] ^ b[i];
return x;
}
......@@ -567,6 +567,13 @@ int FIPS_mode_set(int r);
void OPENSSL_init(void);
/* CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal. It
* takes an amount of time dependent on |len|, but independent of the contents
* of |a| and |b|. Unlike memcmp, it cannot be used to put elements into a
* defined order as the return value when a != b is undefined, other than to be
* non-zero. */
int CRYPTO_memcmp(const void *a, const void *b, size_t len);
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
......
......@@ -151,7 +151,7 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
if (!EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL))
return -1;
if (memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
if (CRYPTO_memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
goto decoding_err;
else
{
......
......@@ -463,7 +463,7 @@ printf("\n");
else
rr->length = 0;
i=s->method->ssl3_enc->mac(s,md,0);
if (i < 0 || mac == NULL || memcmp(md, mac, mac_size) != 0)
if (i < 0 || mac == NULL || CRYPTO_memcmp(md,mac,mac_size) != 0)
{
decryption_failed_or_bad_record_mac = 1;
}
......
......@@ -939,7 +939,7 @@ static int get_server_verify(SSL *s)
s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* SERVER-VERIFY */
p += 1;
if (memcmp(p,s->s2->challenge,s->s2->challenge_length) != 0)
if (CRYPTO_memcmp(p,s->s2->challenge,s->s2->challenge_length) != 0)
{
ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
SSLerr(SSL_F_GET_SERVER_VERIFY,SSL_R_CHALLENGE_IS_DIFFERENT);
......
......@@ -269,8 +269,7 @@ static int ssl2_read_internal(SSL *s, void *buf, int len, int peek)
s->s2->ract_data_length-=mac_size;
ssl2_mac(s,mac,0);
s->s2->ract_data_length-=s->s2->padding;
if ( (memcmp(mac,s->s2->mac_data,
(unsigned int)mac_size) != 0) ||
if ( (CRYPTO_memcmp(mac,s->s2->mac_data,mac_size) != 0) ||
(s->s2->rlength%EVP_CIPHER_CTX_block_size(s->enc_read_ctx) != 0))
{
SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_MAC_DECODE);
......
......@@ -265,7 +265,7 @@ int ssl3_get_finished(SSL *s, int a, int b)
goto f_err;
}
if (memcmp(p, s->s3->tmp.peer_finish_md, i) != 0)
if (CRYPTO_memcmp(p, s->s3->tmp.peer_finish_md, i) != 0)
{
al=SSL_AD_DECRYPT_ERROR;
SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_DIGEST_CHECK_FAILED);
......
......@@ -465,7 +465,7 @@ printf("\n");
#endif
}
i=s->method->ssl3_enc->mac(s,md,0);
if (i < 0 || mac == NULL || memcmp(md, mac, (size_t)mac_size) != 0)
if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0)
{
decryption_failed_or_bad_record_mac = 1;
}
......
......@@ -3125,7 +3125,7 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
HMAC_Update(&hctx, etick, eticklen);
HMAC_Final(&hctx, tick_hmac, NULL);
HMAC_CTX_cleanup(&hctx);
if (memcmp(tick_hmac, etick + eticklen, mlen))
if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen))
return 2;
/* Attempt to decrypt session data */
/* Move p after IV to start of encrypted ticket, update length */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册