From 01f184540232909646c635bc3aa745512da5c4ed Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Tue, 8 Sep 2015 02:44:17 +0200 Subject: [PATCH] harden RSA CRT by implementing the proposed countermeasure ... from ch. 1.3 of [1] [1] https://people.redhat.com/~fweimer/rsa-crt-leaks.pdf --- src/headers/tomcrypt_custom.h | 5 +++++ src/pk/rsa/rsa_exptmod.c | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/headers/tomcrypt_custom.h b/src/headers/tomcrypt_custom.h index 680a2ca..3ed979b 100644 --- a/src/headers/tomcrypt_custom.h +++ b/src/headers/tomcrypt_custom.h @@ -402,6 +402,11 @@ #define LTC_RSA_BLINDING #endif /* LTC_NO_RSA_BLINDING */ +#if defined(LTC_MRSA) && !defined(LTC_NO_RSA_CRT_HARDENING) +/* Enable RSA CRT hardening when doing private key operations by default */ +#define LTC_RSA_CRT_HARDENING +#endif /* LTC_NO_RSA_CRT_HARDENING */ + #if defined(LTC_MECC) && !defined(LTC_NO_ECC_TIMING_RESISTANT) /* Enable ECC timing resistant version by default */ #define LTC_ECC_TIMING_RESISTANT diff --git a/src/pk/rsa/rsa_exptmod.c b/src/pk/rsa/rsa_exptmod.c index dcb036e..78858fe 100644 --- a/src/pk/rsa/rsa_exptmod.c +++ b/src/pk/rsa/rsa_exptmod.c @@ -38,7 +38,7 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen, void *rnd, *rndi /* inverse of rnd */; #endif unsigned long x; - int err; + int err, no_crt; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); @@ -100,7 +100,9 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen, } #endif /* LTC_RSA_BLINDING */ - if ((key->dP == NULL) || (mp_get_digit_count(key->dP) == 0)) { + no_crt = (key->dP == NULL) || (mp_get_digit_count(key->dP) == 0); + + if (no_crt) { /* * In case CRT optimization parameters are not provided, * the private key is directly used to exptmod it @@ -129,6 +131,14 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen, goto error; } #endif + + #ifdef LTC_RSA_CRT_HARDENING + if (!no_crt) { + if ((err = mp_exptmod(tmp, key->e, key->N, tmpa)) != CRYPT_OK) { goto error; } + if ((err = mp_read_unsigned_bin(tmpb, (unsigned char *)in, (int)inlen)) != CRYPT_OK) { goto error; } + if (mp_cmp(tmpa, tmpb) != LTC_MP_EQ) { err = CRYPT_ERROR; goto error; } + } + #endif } else { /* exptmod it */ if ((err = mp_exptmod(tmp, key->e, key->N, tmp)) != CRYPT_OK) { goto error; }