summaryrefslogtreecommitdiff
path: root/cipher/rsa.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2013-09-07 10:06:46 +0200
committerWerner Koch <wk@gnupg.org>2013-09-20 17:41:19 +0200
commit722bfc1e5f2268453db62f38cc46b5ec6ef3adee (patch)
treea59265211609e084227958e308e1d3236c79fcbb /cipher/rsa.c
parent64cd7ab93da7c95cc8aa320c61c6e29f9e2399c4 (diff)
downloadlibgcrypt-722bfc1e5f2268453db62f38cc46b5ec6ef3adee.tar.gz
pk: Move s-exp creation for gcry_pk_decrypt to the modules.
* cipher/pubkey.c (sexp_to_enc): Remove RET_MODERN arg and merge it into FLAGS. (gcry_pk_decrypt): Move result s-exp building into the modules. * src/cipher-proto.h (gcry_pk_decrypt_t): Add some args. * cipher/ecc.c (ecc_decrypt_raw): Change to return an s-exp. * cipher/elgamal.c (elg_decrypt): Ditto. * cipher/rsa.c (rsa_decrypt): Ditto. (rsa_blind, rsa_unblind): Merge into rsa_decrypt. This saves several extra MPI allocations. -- The extra args added to gcry_pk_decrypt_t are a temporary solution unti we move the input s-exp parsing also into the modules. Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'cipher/rsa.c')
-rw-r--r--cipher/rsa.c145
1 files changed, 69 insertions, 76 deletions
diff --git a/cipher/rsa.c b/cipher/rsa.c
index 5754e438..71052711 100644
--- a/cipher/rsa.c
+++ b/cipher/rsa.c
@@ -32,6 +32,7 @@
#include "g10lib.h"
#include "mpi.h"
#include "cipher.h"
+#include "pubkey-internal.h"
typedef struct
@@ -737,47 +738,6 @@ secret (gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey )
-/* 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;
-}
-
/*********************************************
************** interface ******************
*********************************************/
@@ -926,15 +886,18 @@ rsa_encrypt (int algo, gcry_sexp_t *r_result, gcry_mpi_t data,
static gcry_err_code_t
-rsa_decrypt (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
- gcry_mpi_t *skey, int flags)
+rsa_decrypt (int algo, gcry_sexp_t *r_plain, gcry_mpi_t *data,
+ gcry_mpi_t *skey, int flags,
+ enum pk_encoding encoding, int hash_algo,
+ unsigned char *label, size_t labellen)
+
{
+ gpg_err_code_t rc;
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. */
+ gcry_mpi_t plain; /* Decrypted data. */
+ unsigned char *unpad = NULL;
+ size_t unpadlen = 0;
+ unsigned int nbits;
(void)algo;
@@ -946,24 +909,29 @@ rsa_decrypt (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
sk.q = skey[4]; /* Optional. */
sk.u = skey[5]; /* Optional. */
- y = gcry_mpi_snew (gcry_mpi_get_nbits (sk.n));
+ nbits = gcry_mpi_get_nbits (sk.n);
+
+ plain = gcry_mpi_snew (nbits);
/* 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. */
+ gcry_mpi_t r; /* Random number needed for blinding. */
+ gcry_mpi_t ri; /* Modular multiplicative inverse of r. */
+ gcry_mpi_t ciph; /* Blinded data to decrypt. */
/* 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));
+ r = gcry_mpi_snew (nbits);
+ ri = gcry_mpi_snew (nbits);
+ ciph = gcry_mpi_snew (nbits);
- gcry_mpi_randomize (r, gcry_mpi_get_nbits (sk.n), GCRY_WEAK_RANDOM);
+ gcry_mpi_randomize (r, nbits, GCRY_WEAK_RANDOM);
gcry_mpi_mod (r, r, sk.n);
/* Calculate inverse of r. It practically impossible that the
@@ -971,39 +939,64 @@ rsa_decrypt (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
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);
+ /* Do blinding. 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 (ciph, r, sk.e, sk.n);
+ gcry_mpi_mulm (ciph, ciph, data[0], sk.n);
- if (! (flags & PUBKEY_FLAG_NO_BLINDING))
- {
- /* Undo blinding. */
- gcry_mpi_t a = gcry_mpi_copy (y);
+ /* Perform decryption. */
+ secret (plain, ciph, &sk);
- gcry_mpi_release (y);
- y = rsa_unblind (a, ri, sk.n);
+ /* Undo blinding. 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 (plain, plain, ri, sk.n);
- gcry_mpi_release (a);
+ gcry_mpi_release (ciph);
+ gcry_mpi_release (r);
+ gcry_mpi_release (ri);
}
+ else
+ secret (plain, data[0], &sk);
- if (! (flags & PUBKEY_FLAG_NO_BLINDING))
+ /* Reverse the encoding and build the s-expression. */
+ switch (encoding)
{
- /* Deallocate resources needed for blinding. */
- gcry_mpi_release (x);
- gcry_mpi_release (r);
- gcry_mpi_release (ri);
+ case PUBKEY_ENC_PKCS1:
+ rc = _gcry_rsa_pkcs1_decode_for_enc (&unpad, &unpadlen, nbits, plain);
+ mpi_free (plain);
+ plain = NULL;
+ if (!rc)
+ rc = gcry_err_code (gcry_sexp_build (r_plain, NULL, "(value %b)",
+ (int)unpadlen, unpad));
+ break;
+
+ case PUBKEY_ENC_OAEP:
+ rc = _gcry_rsa_oaep_decode (&unpad, &unpadlen,
+ nbits, hash_algo, plain, label, labellen);
+ mpi_free (plain);
+ plain = NULL;
+ if (!rc)
+ rc = gcry_err_code (gcry_sexp_build (r_plain, NULL, "(value %b)",
+ (int)unpadlen, unpad));
+ break;
+
+ default:
+ /* Raw format. For backward compatibility we need to assume a
+ signed mpi by using the sexp format string "%m". */
+ rc = gcry_err_code
+ (gcry_sexp_build (r_plain, NULL,
+ (flags & PUBKEY_FLAG_LEGACYRESULT)? "%m":"(value %m)",
+ plain));
+ break;
}
- /* Copy out result. */
- *result = y;
+ gcry_free (unpad);
+ mpi_free (plain);
- return GPG_ERR_NO_ERROR;
+ return rc;
}