diff options
author | Paul Bakker <p.j.bakker@polarssl.org> | 2013-02-28 18:06:26 +0100 |
---|---|---|
committer | Paul Bakker <p.j.bakker@polarssl.org> | 2013-03-06 18:01:03 +0100 |
commit | 8804f69d46ef5cb5fad403f4df8e14725966443d (patch) | |
tree | a043915ea04358ebdd14b46976d7fdcd7c4d1a0a | |
parent | a43231c5a53622c19a314e7966e43cc60bb5aed1 (diff) | |
download | mbedtls-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-- | ChangeLog | 3 | ||||
-rw-r--r-- | library/rsa.c | 43 |
2 files changed, 35 insertions, 11 deletions
@@ -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 ); |