CVE-2013-0169: Make CBC decoding constant time
(cherry-picked from 2c082d25fc3f0dd6e56c45407fe10638b904083c)
Bug: 8017911
Bug: 8095088
Change-Id: I57556e120fd1f585d38739d0d6aaf02bcbe45fbd
diff --git a/crypto/cryptlib.c b/crypto/cryptlib.c
index 50fd492..d47ab55 100644
--- a/crypto/cryptlib.c
+++ b/crypto/cryptlib.c
@@ -924,3 +924,16 @@
}
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;
+ }
diff --git a/crypto/crypto.h b/crypto/crypto.h
index 6aeda0a..793a325 100644
--- a/crypto/crypto.h
+++ b/crypto/crypto.h
@@ -574,6 +574,13 @@
#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.
diff --git a/crypto/evp/c_allc.c b/crypto/evp/c_allc.c
index 2a45d43..e230e60 100644
--- a/crypto/evp/c_allc.c
+++ b/crypto/evp/c_allc.c
@@ -195,11 +195,13 @@
EVP_add_cipher(EVP_aes_256_xts());
EVP_add_cipher_alias(SN_aes_256_cbc,"AES256");
EVP_add_cipher_alias(SN_aes_256_cbc,"aes256");
+#if 0 /* Disabled because of timing side-channel leaks. */
#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1());
EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
#endif
#endif
+#endif
#ifndef OPENSSL_NO_CAMELLIA
EVP_add_cipher(EVP_camellia_128_ecb());
diff --git a/crypto/rsa/rsa_oaep.c b/crypto/rsa/rsa_oaep.c
index 553d212..af4d24a 100644
--- a/crypto/rsa/rsa_oaep.c
+++ b/crypto/rsa/rsa_oaep.c
@@ -149,7 +149,7 @@
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
{