[cryptography] blinding is in libgcrypt but NOT in gnupg?
Jake
jake at spaz.org
Thu Aug 22 23:56:53 EDT 2013
as you all know, I have been trying to find blinding for GnuPG, and
someone to help implement it as a seperate (external) operation.
I was told that blinding was used in RSA decryption to repel timing
attacks. But I couldn't find it anywhere in the GnuPG source code.
/* We use blinding by default to mitigate timing attacks which can
be practically mounted over the network as shown by Brumley and
Boney in 2003. */
I found it in libgcrypt. I don't understand why it's not in gnupg.
It looks to my untrained eye that gnupg and libgcrypt had a common
ancestor, but i'm not sure when that was. Anyway, here is what I found.
Does anyone have any idea why it's not in gnupg, and is that a problem?
Does anyone want to help me merge it in and get it reviewed and pulled?
from libgcrypt-1.5.0/cipher/rsa.c (NOT present in gnupg/cipher/rsa.c)
/* Perform RSA blinding. */
static gcry_mpi_t
rsa_blind (gcry_mpi_t x, gcry_mpi_t r, gcry_mpi_t e, gcry_mpi_t n)
{
/* A helper. */
gcry_mpi_t a;
/* Result. */
gcry_mpi_t y;
a = gcry_mpi_snew (gcry_mpi_get_nbits (n));
y = gcry_mpi_snew (gcry_mpi_get_nbits (n));
/* Now we calculate: y = (x * r^e) mod n, where r is the random
number, e is the public exponent, x is the non-blinded data and n
is the RSA modulus. */
gcry_mpi_powm (a, r, e, n);
gcry_mpi_mulm (y, a, x, n);
gcry_mpi_release (a);
return y;
}
/* Undo RSA blinding. */
static gcry_mpi_t
rsa_unblind (gcry_mpi_t x, gcry_mpi_t ri, gcry_mpi_t n)
{
gcry_mpi_t y;
y = gcry_mpi_snew (gcry_mpi_get_nbits (n));
/* Here we calculate: y = (x * r^-1) mod n, where x is the blinded
decrypted data, ri is the modular multiplicative inverse of r and
n is the RSA modulus. */
gcry_mpi_mulm (y, ri, x, n);
return y;
}
static gcry_err_code_t
rsa_decrypt (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
gcry_mpi_t *skey, int flags)
{
RSA_secret_key sk;
gcry_mpi_t r = MPI_NULL; /* Random number needed for blinding. */
gcry_mpi_t ri = MPI_NULL; /* Modular multiplicative inverse of
r. */
gcry_mpi_t x = MPI_NULL; /* Data to decrypt. */
gcry_mpi_t y; /* Result. */
(void)algo;
/* Extract private key. */
sk.n = skey[0];
sk.e = skey[1];
sk.d = skey[2];
sk.p = skey[3]; /* Optional. */
sk.q = skey[4]; /* Optional. */
sk.u = skey[5]; /* Optional. */
y = gcry_mpi_snew (gcry_mpi_get_nbits (sk.n));
/* We use blinding by default to mitigate timing attacks which can
be practically mounted over the network as shown by Brumley and
Boney in 2003. */
if (! (flags & PUBKEY_FLAG_NO_BLINDING))
{
/* Initialize blinding. */
/* First, we need a random number r between 0 and n - 1, which
is relatively prime to n (i.e. it is neither p nor q). The
random number needs to be only unpredictable, thus we employ
the gcry_create_nonce function by using GCRY_WEAK_RANDOM with
gcry_mpi_randomize. */
r = gcry_mpi_snew (gcry_mpi_get_nbits (sk.n));
ri = gcry_mpi_snew (gcry_mpi_get_nbits (sk.n));
gcry_mpi_randomize (r, gcry_mpi_get_nbits (sk.n), GCRY_WEAK_RANDOM);
gcry_mpi_mod (r, r, sk.n);
/* Calculate inverse of r. It practically impossible that the
following test fails, thus we do not add code to release
allocated resources. */
if (!gcry_mpi_invm (ri, r, sk.n))
return GPG_ERR_INTERNAL;
}
if (! (flags & PUBKEY_FLAG_NO_BLINDING))
x = rsa_blind (data[0], r, sk.e, sk.n);
else
x = data[0];
/* Do the encryption. */
secret (y, x, &sk);
if (! (flags & PUBKEY_FLAG_NO_BLINDING))
{
/* Undo blinding. */
gcry_mpi_t a = gcry_mpi_copy (y);
gcry_mpi_release (y);
y = rsa_unblind (a, ri, sk.n);
gcry_mpi_release (a);
}
if (! (flags & PUBKEY_FLAG_NO_BLINDING))
{
/* Deallocate resources needed for blinding. */
gcry_mpi_release (x);
gcry_mpi_release (r);
gcry_mpi_release (ri);
}
/* Copy out result. */
*result = y;
return GPG_ERR_NO_ERROR;
}
More information about the cryptography
mailing list