diff --git a/src/pk/rsa/rsa_exptmod.c b/src/pk/rsa/rsa_exptmod.c index 101a766..a05df6d 100644 --- a/src/pk/rsa/rsa_exptmod.c +++ b/src/pk/rsa/rsa_exptmod.c @@ -7,6 +7,8 @@ * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + * + * Added RSA blinding --nmav */ #include "tomcrypt.h" @@ -31,7 +33,7 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, int which, rsa_key *key) { - void *tmp, *tmpa, *tmpb; + void *tmp, *tmpa, *tmpb, *rnd, *rndi /* inverse of rnd */; unsigned long x; int err; @@ -51,8 +53,11 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen, } /* init and copy into tmp */ - if ((err = mp_init_multi(&tmp, &tmpa, &tmpb, NULL)) != CRYPT_OK) { return err; } - if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, (int)inlen)) != CRYPT_OK) { goto error; } + if ((err = mp_init_multi(&tmp, &tmpa, &tmpb, &rnd, &rndi, NULL)) != CRYPT_OK) + { return err; } + if ((err = mp_read_unsigned_bin(&tmp, (unsigned char *)in, (int)inlen)) != CRYPT_OK) + { goto error; } + /* sanity check on the input */ if (mp_cmp(key->N, tmp) == LTC_MP_LT) { @@ -62,6 +67,30 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen, /* are we using the private exponent and is the key optimized? */ if (which == PK_PRIVATE) { + /* do blinding */ + err = mp_rand(rnd, mp_count_bits(key->N)); + if (err != CRYPT_OK) { + goto error; + } + + /* rndi = 1/rnd mod N */ + err = mp_invmod(rnd, key->N, rndi); + if (err != CRYPT_OK) { + goto error; + } + + /* rnd = rnd^e */ + err = mp_exptmod( rnd, key->e, key->N, rnd); + if (err != CRYPT_OK) { + goto error; + } + + /* tmp = tmp*rnd mod N */ + err = mp_mulmod( tmp, rnd, key->N, tmp); + if (err != CRYPT_OK) { + goto error; + } + /* tmpa = tmp^dP mod p */ if ((err = mp_exptmod(tmp, key->dP, key->p, tmpa)) != CRYPT_OK) { goto error; } @@ -75,6 +104,12 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen, /* tmp = tmpb + q * tmp */ if ((err = mp_mul(tmp, key->q, tmp)) != CRYPT_OK) { goto error; } if ((err = mp_add(tmp, tmpb, tmp)) != CRYPT_OK) { goto error; } + + /* unblind */ + err = mp_mulmod( tmp, rndi, key->N, tmp); + if (err != CRYPT_OK) { + goto error; + } } else { /* exptmod it */ if ((err = mp_exptmod(tmp, key->e, key->N, tmp)) != CRYPT_OK) { goto error; } @@ -102,7 +137,7 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen, /* clean up and return */ err = CRYPT_OK; error: - mp_clear_multi(tmp, tmpa, tmpb, NULL); + mp_clear_multi(tmp, tmpa, tmpb, rnd, rndi, NULL); return err; }