Removed timing differences due to bad padding from RSA decrypt for

PKCS#1 v1.5 operations
(cherry picked from commit 8804f69d46)

Conflicts:
	ChangeLog
	library/rsa.c
This commit is contained in:
Paul Bakker 2013-03-11 16:51:05 +01:00
parent 0a971b5dc8
commit e73a77f656
2 changed files with 35 additions and 11 deletions

View File

@ -9,6 +9,9 @@ Changes
Security Security
* Removed further timing differences during SSL message decryption in * Removed further timing differences during SSL message decryption in
ssl_decrypt_buf() 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.1.5 released on 2013-01-16 = Version 1.1.5 released on 2013-01-16
Bugfix Bugfix

View File

@ -484,9 +484,9 @@ int rsa_pkcs1_decrypt( rsa_context *ctx,
unsigned char *output, unsigned char *output,
size_t output_max_len) size_t output_max_len)
{ {
int ret; int ret, correct = 1;
size_t ilen; size_t ilen, pad_count = 0;
unsigned char *p; unsigned char *p, *q;
unsigned char bt; unsigned char bt;
unsigned char buf[1024]; unsigned char buf[1024];
#if defined(POLARSSL_PKCS1_V21) #if defined(POLARSSL_PKCS1_V21)
@ -515,36 +515,57 @@ int rsa_pkcs1_decrypt( rsa_context *ctx,
case RSA_PKCS_V15: case RSA_PKCS_V15:
if( *p++ != 0 ) if( *p++ != 0 )
return( POLARSSL_ERR_RSA_INVALID_PADDING ); correct = 0;
bt = *p++; bt = *p++;
if( ( bt != RSA_CRYPT && mode == RSA_PRIVATE ) || if( ( bt != RSA_CRYPT && mode == RSA_PRIVATE ) ||
( bt != RSA_SIGN && mode == RSA_PUBLIC ) ) ( bt != RSA_SIGN && mode == RSA_PUBLIC ) )
{ {
return( POLARSSL_ERR_RSA_INVALID_PADDING ); correct = 0;
} }
if( bt == RSA_CRYPT ) if( bt == RSA_CRYPT )
{ {
while( *p != 0 && p < buf + ilen - 1 ) while( *p != 0 && p < buf + ilen - 1 )
p++; pad_count += ( *p++ != 0 );
if( *p != 0 || p >= buf + ilen - 1 ) correct &= ( *p == 0 && p < buf + ilen - 1 );
return( POLARSSL_ERR_RSA_INVALID_PADDING );
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++; p++;
} }
else else
{ {
while( *p == 0xFF && p < buf + ilen - 1 ) while( *p == 0xFF && p < buf + ilen - 1 )
p++; pad_count += ( *p++ == 0xFF );
if( *p != 0 || p >= buf + ilen - 1 ) correct &= ( *p == 0 && p < buf + ilen - 1 );
return( POLARSSL_ERR_RSA_INVALID_PADDING );
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++; p++;
} }
if( correct == 0 )
return( POLARSSL_ERR_RSA_INVALID_PADDING );
break; break;
#if defined(POLARSSL_PKCS1_V21) #if defined(POLARSSL_PKCS1_V21)