aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Bakker <p.j.bakker@polarssl.org>2013-02-28 18:06:26 +0100
committerPaul Bakker <p.j.bakker@polarssl.org>2013-03-06 18:01:03 +0100
commit8804f69d46ef5cb5fad403f4df8e14725966443d (patch)
treea043915ea04358ebdd14b46976d7fdcd7c4d1a0a
parenta43231c5a53622c19a314e7966e43cc60bb5aed1 (diff)
downloadmbedtls-8804f69d46ef5cb5fad403f4df8e14725966443d.zip
mbedtls-8804f69d46ef5cb5fad403f4df8e14725966443d.tar.gz
mbedtls-8804f69d46ef5cb5fad403f4df8e14725966443d.tar.bz2
Removed timing differences due to bad padding from RSA decrypt for
PKCS#1 v1.5 operations
-rw-r--r--ChangeLog3
-rw-r--r--library/rsa.c43
2 files changed, 35 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index ba3afd4..fa54120 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -17,6 +17,9 @@ Changes
Security
* Removed further timing differences during SSL message decryption in
ssl_decrypt_buf()
+ * Removed timing differences due to bad padding from
+ rsa_rsaes_pkcs1_v15_decrypt() and rsa_pkcs1_decrypt() for PKCS#1 v1.5
+ operations
= Version 1.2.5 released 2013-02-02
Changes
diff --git a/library/rsa.c b/library/rsa.c
index cc14d8e..e53d9a2 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -623,9 +623,9 @@ int rsa_rsaes_pkcs1_v15_decrypt( rsa_context *ctx,
unsigned char *output,
size_t output_max_len)
{
- int ret;
- size_t ilen;
- unsigned char *p;
+ int ret, correct = 1;
+ size_t ilen, pad_count = 0;
+ unsigned char *p, *q;
unsigned char bt;
unsigned char buf[POLARSSL_MPI_MAX_SIZE];
@@ -647,36 +647,57 @@ int rsa_rsaes_pkcs1_v15_decrypt( rsa_context *ctx,
p = buf;
if( *p++ != 0 )
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ correct = 0;
bt = *p++;
if( ( bt != RSA_CRYPT && mode == RSA_PRIVATE ) ||
( bt != RSA_SIGN && mode == RSA_PUBLIC ) )
{
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ correct = 0;
}
if( bt == RSA_CRYPT )
{
while( *p != 0 && p < buf + ilen - 1 )
- p++;
+ pad_count += ( *p++ != 0 );
- if( *p != 0 || p >= buf + ilen - 1 )
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ correct &= ( *p == 0 && p < buf + ilen - 1 );
+
+ q = p;
+ // Also pass over all other bytes to reduce timing differences
+ //
+ while ( q < buf + ilen - 1 )
+ pad_count += ( *q++ != 0 );
+
+ // Prevent compiler optimization of pad_count
+ //
+ correct |= pad_count & 0x100000; /* Always 0 unless 1M bit keys */
p++;
}
else
{
while( *p == 0xFF && p < buf + ilen - 1 )
- p++;
+ pad_count += ( *p++ == 0xFF );
- if( *p != 0 || p >= buf + ilen - 1 )
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ correct &= ( *p == 0 && p < buf + ilen - 1 );
+
+ q = p;
+ // Also pass over all other bytes to reduce timing differences
+ //
+ while ( q < buf + ilen - 1 )
+ pad_count += ( *q++ != 0 );
+
+ // Prevent compiler optimization of pad_count
+ //
+ correct |= pad_count & 0x100000; /* Always 0 unless 1M bit keys */
p++;
}
+ if( correct == 0 )
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+
if (ilen - (p - buf) > output_max_len)
return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );