Commit 2ee79888 authored by Ben Laurie's avatar Ben Laurie
Browse files

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.
parent ffcf4c61
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -925,3 +925,16 @@ void OpenSSLDie(const char *file,int line,const char *assertion)
	}

void *OPENSSL_stderr(void)	{ return stderr; }

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;
	}
+7 −0
Original line number Diff line number Diff line
@@ -574,6 +574,13 @@ void OPENSSL_init(void);
#define fips_cipher_abort(alg) while(0)
#endif

/* 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.
+1 −1
Original line number Diff line number Diff line
@@ -149,7 +149,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
		{
+1 −1
Original line number Diff line number Diff line
@@ -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;
			}
+1 −1
Original line number Diff line number Diff line
@@ -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);
Loading