Add counter-measure against RSA-CRT attack

https://securityblog.redhat.com/2015/09/02/factoring-rsa-keys-with-tls-perfect-forward-secrecy/

backport of 5f50104
This commit is contained in:
Manuel Pégourié-Gonnard 2015-09-03 20:03:15 +02:00
parent bb564e0fb4
commit a1cdcd2364
2 changed files with 43 additions and 3 deletions

View File

@ -6,6 +6,9 @@ Security
* Fix possible client-side NULL pointer dereference (read) when the client * Fix possible client-side NULL pointer dereference (read) when the client
tries to continue the handshake after it failed (a misuse of the API). tries to continue the handshake after it failed (a misuse of the API).
(Found by GDS Labs using afl-fuzz, patch provided by GDS Labs.) (Found by GDS Labs using afl-fuzz, patch provided by GDS Labs.)
* Add countermeasure against Lenstra's RSA-CRT attack for PKCS#1 v1.5
signatures. (Found by Florian Weimer, Red Hat.)
https://securityblog.redhat.com/2015/09/02/factoring-rsa-keys-with-tls-perfect-forward-secrecy/
Bugfix Bugfix
* Setting SSL_MIN_DHM_BYTES in config.h had no effect (overriden in ssl.h) * Setting SSL_MIN_DHM_BYTES in config.h had no effect (overriden in ssl.h)

View File

@ -52,6 +52,8 @@
#else #else
#include <stdio.h> #include <stdio.h>
#define polarssl_printf printf #define polarssl_printf printf
#define polarssl_malloc malloc
#define polarssl_free free
#endif #endif
/* /*
@ -1005,6 +1007,11 @@ int rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx,
size_t nb_pad, olen, oid_size = 0; size_t nb_pad, olen, oid_size = 0;
unsigned char *p = sig; unsigned char *p = sig;
const char *oid = NULL; const char *oid = NULL;
unsigned char *sig_try = NULL, *verif = NULL;
size_t i;
unsigned char diff;
volatile unsigned char diff_no_optimize;
int ret;
if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 ) if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 )
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
@ -1067,9 +1074,39 @@ int rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx,
memcpy( p, hash, hashlen ); memcpy( p, hash, hashlen );
} }
return( ( mode == RSA_PUBLIC ) if( mode == RSA_PUBLIC )
? rsa_public( ctx, sig, sig ) return( rsa_public( ctx, sig, sig ) );
: rsa_private( ctx, f_rng, p_rng, sig, sig ) );
/*
* In order to prevent Lenstra's attack, make the signature in a
* temporary buffer and check it before returning it.
*/
sig_try = polarssl_malloc( ctx->len );
verif = polarssl_malloc( ctx->len );
if( sig_try == NULL || verif == NULL )
return( POLARSSL_ERR_MPI_MALLOC_FAILED );
MPI_CHK( rsa_private( ctx, f_rng, p_rng, sig, sig_try ) );
MPI_CHK( rsa_public( ctx, sig_try, verif ) );
/* Compare in constant time just in case */
for( diff = 0, i = 0; i < ctx->len; i++ )
diff |= verif[i] ^ sig[i];
diff_no_optimize = diff;
if( diff_no_optimize != 0 )
{
ret = POLARSSL_ERR_RSA_PRIVATE_FAILED;
goto cleanup;
}
memcpy( sig, sig_try, ctx->len );
cleanup:
polarssl_free( sig_try );
polarssl_free( verif );
return( ret );
} }
#endif /* POLARSSL_PKCS1_V15 */ #endif /* POLARSSL_PKCS1_V15 */