summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMoritz Schulte <mo@g10code.com>2003-03-26 10:56:50 +0000
committerMoritz Schulte <mo@g10code.com>2003-03-26 10:56:50 +0000
commitfa96757af62826f3293134c3731b23bf38dad48e (patch)
tree58fd645156d60aac584d20746914dc263c7d665d
parent7b2cbee4af924336e9071f5f0890ce9553f377ec (diff)
downloadlibgcrypt-fa96757af62826f3293134c3731b23bf38dad48e.tar.gz
2003-03-26 Moritz Schulte <moritz@g10code.com>
* dynload.c (_gcry_enum_gnupgext_pubkeys): Adjust `encrypt' and `decrypt' function arguments. (_gcry_enum_gnupgext_pubkeys): Likewise. * dynload.h: Likewise. * pubkey.c (dummy_decrypt): Add argument: int flags. (dummy_encrypt): Likewise. * elgamal.c (_gcry_elg_encrypt): Add argument: int flags. (_gcry_elg_decrypt): Likewise. * rsa.c (_gcry_rsa_encrypt): Add argument: int flags. (_gcry_rsa_decrypt): Likewise. * pubkey.c: Add `flags' argument to members `encrypt' and `decrypt' of struct `pubkey_table_s'. * rsa.h: Add `flags' argument to function declarations. * elgamal.h: Likewise. * pubkey.c (sexp_data_to_mpi): New variable: int parsed_flags. (sexp_data_to_mpi): Set `parsed_flags'. (sexp_data_to_mpi): New argument: int *flags. (gcry_pk_encrypt): New variable: int flags. (gcry_pk_encrypt): Pass `flags' to pubkey_encrypt. (pubkey_encrypt): New variable: int flags. (pubkey_encrypt): Pass `flags' to pubkey encrypt function. (pubkey_decrypt): Likewise. (pubkey_decrypt): Pass `flags' to pubkey encrypt function. (gcry_pk_encrypt): Include `flags' s-exp in return list. (sexp_to_enc): New argument: int *flags. (gcry_pk_decrypt): New variable: int flags. (gcry_pk_decrypt): Pass `flags' to pubkey_decrypt. (sexp_to_enc): New variable: int parsed_flags. (sexp_to_enc): Set `parsed_flags'.
-rw-r--r--cipher/ChangeLog38
-rw-r--r--cipher/dynload.c8
-rw-r--r--cipher/dynload.h4
-rw-r--r--cipher/elgamal.c4
-rw-r--r--cipher/elgamal.h4
-rw-r--r--cipher/pubkey.c74
-rw-r--r--cipher/rsa.c114
-rw-r--r--cipher/rsa.h4
8 files changed, 209 insertions, 41 deletions
diff --git a/cipher/ChangeLog b/cipher/ChangeLog
index 1e0739bb..3f00e2da 100644
--- a/cipher/ChangeLog
+++ b/cipher/ChangeLog
@@ -1,3 +1,41 @@
+2003-03-26 Moritz Schulte <moritz@g10code.com>
+
+ * dynload.c (_gcry_enum_gnupgext_pubkeys): Adjust `encrypt' and
+ `decrypt' function arguments.
+ (_gcry_enum_gnupgext_pubkeys): Likewise.
+ * dynload.h: Likewise.
+
+ * pubkey.c (dummy_decrypt): Add argument: int flags.
+ (dummy_encrypt): Likewise.
+
+ * elgamal.c (_gcry_elg_encrypt): Add argument: int flags.
+ (_gcry_elg_decrypt): Likewise.
+
+ * rsa.c (_gcry_rsa_encrypt): Add argument: int flags.
+ (_gcry_rsa_decrypt): Likewise.
+
+ * pubkey.c: Add `flags' argument to members `encrypt' and
+ `decrypt' of struct `pubkey_table_s'.
+
+ * rsa.h: Add `flags' argument to function declarations.
+ * elgamal.h: Likewise.
+
+ * pubkey.c (sexp_data_to_mpi): New variable: int parsed_flags.
+ (sexp_data_to_mpi): Set `parsed_flags'.
+ (sexp_data_to_mpi): New argument: int *flags.
+ (gcry_pk_encrypt): New variable: int flags.
+ (gcry_pk_encrypt): Pass `flags' to pubkey_encrypt.
+ (pubkey_encrypt): New variable: int flags.
+ (pubkey_encrypt): Pass `flags' to pubkey encrypt function.
+ (pubkey_decrypt): Likewise.
+ (pubkey_decrypt): Pass `flags' to pubkey encrypt function.
+ (gcry_pk_encrypt): Include `flags' s-exp in return list.
+ (sexp_to_enc): New argument: int *flags.
+ (gcry_pk_decrypt): New variable: int flags.
+ (gcry_pk_decrypt): Pass `flags' to pubkey_decrypt.
+ (sexp_to_enc): New variable: int parsed_flags.
+ (sexp_to_enc): Set `parsed_flags'.
+
2003-03-22 Simon Josefsson <jas@extundo.com>
* cipher.c (gcry_cipher_open, do_cbc_encrypt)
diff --git a/cipher/dynload.c b/cipher/dynload.c
index 4f00a1e7..d386ea2a 100644
--- a/cipher/dynload.c
+++ b/cipher/dynload.c
@@ -221,8 +221,8 @@ _gcry_enum_gnupgext_pubkeys( void **enum_context, int *algo,
int (**generate)( int algo, unsigned int nbits, unsigned long use_e,
MPI *skey, MPI **retfactors ),
int (**check_secret_key)( int algo, MPI *skey ),
- int (**encryptf)( int algo, MPI *resarr, MPI data, MPI *pkey ),
- int (**decryptf)( int algo, MPI *result, MPI *data, MPI *skey ),
+ int (**encryptf)( int algo, MPI *resarr, MPI data, MPI *pkey, int flags ),
+ int (**decryptf)( int algo, MPI *result, MPI *data, MPI *skey, int flags ),
int (**sign)( int algo, MPI *resarr, MPI data, MPI *skey ),
int (**verify)( int algo, MPI hash, MPI *data, MPI *pkey,
int (*cmp)(void *, MPI), void *opaquev ),
@@ -234,8 +234,8 @@ _gcry_enum_gnupgext_pubkeys( void **enum_context, int *algo,
int (**)( int, unsigned int, unsigned long,
MPI *, MPI **),
int (**)( int, MPI * ),
- int (**)( int, MPI *, MPI , MPI * ),
- int (**)( int, MPI *, MPI *, MPI * ),
+ int (**)( int, MPI *, MPI , MPI *, int flags ),
+ int (**)( int, MPI *, MPI *, MPI *, int flags ),
int (**)( int, MPI *, MPI , MPI * ),
int (**)( int, MPI , MPI *, MPI *,
int (*)(void*,MPI), void *),
diff --git a/cipher/dynload.h b/cipher/dynload.h
index 9258352d..0636948d 100644
--- a/cipher/dynload.h
+++ b/cipher/dynload.h
@@ -49,8 +49,8 @@ _gcry_enum_gnupgext_pubkeys( void **enum_context, int *algo,
int (**generate)( int algo, unsigned int nbits, unsigned long use_e,
MPI *skey, MPI **retfactors ),
int (**check_secret_key)( int algo, MPI *skey ),
- int (**encryptf)( int algo, MPI *resarr, MPI data, MPI *pkey ),
- int (**decryptf)( int algo, MPI *result, MPI *data, MPI *skey ),
+ int (**encryptf)( int algo, MPI *resarr, MPI data, MPI *pkey, int flags ),
+ int (**decryptf)( int algo, MPI *result, MPI *data, MPI *skey, int flags ),
int (**sign)( int algo, MPI *resarr, MPI data, MPI *skey ),
int (**verify)( int algo, MPI hash, MPI *data, MPI *pkey,
int (*cmp)(void *, MPI), void *opaquev ),
diff --git a/cipher/elgamal.c b/cipher/elgamal.c
index ea3a8dd6..a4b54254 100644
--- a/cipher/elgamal.c
+++ b/cipher/elgamal.c
@@ -538,7 +538,7 @@ _gcry_elg_check_secret_key( int algo, MPI *skey )
int
-_gcry_elg_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
+_gcry_elg_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey, int flags)
{
ELG_public_key pk;
@@ -557,7 +557,7 @@ _gcry_elg_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
}
int
-_gcry_elg_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
+_gcry_elg_decrypt( int algo, MPI *result, MPI *data, MPI *skey, int flags)
{
ELG_secret_key sk;
diff --git a/cipher/elgamal.h b/cipher/elgamal.h
index ae9f296a..80180646 100644
--- a/cipher/elgamal.h
+++ b/cipher/elgamal.h
@@ -23,8 +23,8 @@
int _gcry_elg_generate( int algo, unsigned int nbits, unsigned long dummy,
MPI *skey, MPI **retfactors );
int _gcry_elg_check_secret_key( int algo, MPI *skey );
-int _gcry_elg_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey );
-int _gcry_elg_decrypt( int algo, MPI *result, MPI *data, MPI *skey );
+int _gcry_elg_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey, int flags);
+int _gcry_elg_decrypt( int algo, MPI *result, MPI *data, MPI *skey, int flags );
int _gcry_elg_sign( int algo, MPI *resarr, MPI data, MPI *skey );
int _gcry_elg_verify( int algo, MPI hash, MPI *data, MPI *pkey,
int (*cmp)(void *, MPI), void *opaquev );
diff --git a/cipher/pubkey.c b/cipher/pubkey.c
index d0a493de..a0497d63 100644
--- a/cipher/pubkey.c
+++ b/cipher/pubkey.c
@@ -37,6 +37,8 @@
#define TABLE_SIZE 10
+
+
struct pubkey_table_s {
const char *name;
int algo;
@@ -48,8 +50,8 @@ struct pubkey_table_s {
int (*generate)(int algo, unsigned int nbits, unsigned long use_e,
MPI *skey, MPI **retfactors );
int (*check_secret_key)( int algo, MPI *skey );
- int (*encrypt)( int algo, MPI *resarr, MPI data, MPI *pkey );
- int (*decrypt)( int algo, MPI *result, MPI *data, MPI *skey );
+ int (*encrypt)( int algo, MPI *resarr, MPI data, MPI *pkey, int flags);
+ int (*decrypt)( int algo, MPI *result, MPI *data, MPI *skey, int flags);
int (*sign)( int algo, MPI *resarr, MPI data, MPI *skey );
int (*verify)( int algo, MPI hash, MPI *data, MPI *pkey,
int (*cmp)(void *, MPI), void *opaquev );
@@ -106,7 +108,7 @@ static struct {
};
-static int pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey );
+static int pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey, int flags);
static int pubkey_sign( int algo, MPI *resarr, MPI hash, MPI *skey );
static int pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey,
int (*cmp)(void *, MPI), void *opaque );
@@ -121,11 +123,11 @@ dummy_check_secret_key( int algo, MPI *skey )
{ log_bug("no check_secret_key() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; }
static int
-dummy_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
+dummy_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey, int flags)
{ log_bug("no encrypt() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; }
static int
-dummy_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
+dummy_decrypt( int algo, MPI *result, MPI *data, MPI *skey, int flags)
{ log_bug("no decrypt() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; }
static int
@@ -526,7 +528,8 @@ pubkey_check_secret_key( int algo, MPI *skey )
* algorithm allows this - check with pubkey_get_nenc() )
*/
static int
-pubkey_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
+pubkey_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey,
+ int flags )
{
int i, rc;
@@ -540,7 +543,7 @@ pubkey_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
do {
for(i=0; pubkey_table[i].name; i++ )
if( pubkey_table[i].algo == algo ) {
- rc = (*pubkey_table[i].encrypt)( algo, resarr, data, pkey );
+ rc = (*pubkey_table[i].encrypt)( algo, resarr, data, pkey, flags);
goto ready;
}
} while( load_pubkey_modules() );
@@ -563,7 +566,8 @@ pubkey_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
* newly allocated mpi or NULL in case of an error.
*/
static int
-pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
+pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey,
+ int flags)
{
int i, rc;
@@ -579,7 +583,7 @@ pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
do {
for(i=0; pubkey_table[i].name; i++ )
if( pubkey_table[i].algo == algo ) {
- rc = (*pubkey_table[i].decrypt)( algo, result, data, skey );
+ rc = (*pubkey_table[i].decrypt)( algo, result, data, skey, flags );
goto ready;
}
} while( load_pubkey_modules() );
@@ -867,7 +871,8 @@ sexp_to_sig( GCRY_SEXP sexp, MPI **retarray, int *retalgo)
*/
static int
sexp_to_enc( GCRY_SEXP sexp, MPI **retarray, int *retalgo,
- int *ret_modern, int *ret_want_pkcs1)
+ int *ret_modern, int *ret_want_pkcs1,
+ int *flags)
{
GCRY_SEXP list, l2;
const char *name;
@@ -875,6 +880,7 @@ sexp_to_enc( GCRY_SEXP sexp, MPI **retarray, int *retalgo,
size_t n;
int i, idx;
int algo;
+ int parsed_flags = 0;
const char *elems;
GCRY_MPI *array;
@@ -909,6 +915,8 @@ sexp_to_enc( GCRY_SEXP sexp, MPI **retarray, int *retalgo,
; /* just a dummy because it is the default */
else if ( n == 5 && !memcmp (s, "pkcs1", 5))
*ret_want_pkcs1 = 1;
+ else if ( n == 11 && !memcmp (s, "no-blinding", 11))
+ parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
else
{
gcry_sexp_release (l2);
@@ -972,6 +980,8 @@ sexp_to_enc( GCRY_SEXP sexp, MPI **retarray, int *retalgo,
*retarray = array;
*retalgo = algo;
+ *flags = parsed_flags;
+
return 0;
}
@@ -997,7 +1007,7 @@ sexp_to_enc( GCRY_SEXP sexp, MPI **retarray, int *retalgo,
*/
static int
sexp_data_to_mpi (GcrySexp input, unsigned int nbits, GcryMPI *ret_mpi,
- int for_encryption)
+ int for_encryption, int *flags)
{
int rc = 0;
GcrySexp ldata, lhash, lvalue;
@@ -1005,7 +1015,11 @@ sexp_data_to_mpi (GcrySexp input, unsigned int nbits, GcryMPI *ret_mpi,
size_t n;
const char *s;
int is_raw = 0, is_pkcs1 = 0, unknown_flag=0;
+ int parsed_flags = 0, dummy_flags;
+ if (! flags)
+ flags = &dummy_flags;
+
*ret_mpi = NULL;
ldata = gcry_sexp_find_token (input, "data", 0);
if (!ldata)
@@ -1028,6 +1042,8 @@ sexp_data_to_mpi (GcrySexp input, unsigned int nbits, GcryMPI *ret_mpi,
is_raw = 1;
else if ( n == 5 && !memcmp (s, "pkcs1", 5))
is_pkcs1 = 1;
+ else if (n == 11 && ! memcmp (s, "no-blinding", 11))
+ parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
else
unknown_flag = 1;
}
@@ -1206,6 +1222,10 @@ sexp_data_to_mpi (GcrySexp input, unsigned int nbits, GcryMPI *ret_mpi,
gcry_sexp_release (ldata);
gcry_sexp_release (lhash);
gcry_sexp_release (lvalue);
+
+ if (! rc)
+ *flags = parsed_flags;
+
return rc;
}
@@ -1237,8 +1257,8 @@ gcry_pk_encrypt (GCRY_SEXP *r_ciph, GCRY_SEXP s_data, GCRY_SEXP s_pkey)
{
MPI *pkey, data, *ciph;
const char *key_algo_name, *algo_name, *algo_elems;
- int i, rc, algo;
-
+ int i, rc, algo, flags;
+
*r_ciph = NULL;
/* get the key */
rc = sexp_to_key( s_pkey, 0, &pkey, &algo, &i);
@@ -1267,7 +1287,8 @@ gcry_pk_encrypt (GCRY_SEXP *r_ciph, GCRY_SEXP s_data, GCRY_SEXP s_pkey)
algo_elems = enc_info_table[i].elements;
/* get the stuff we want to encrypt */
- rc = sexp_data_to_mpi (s_data, gcry_pk_get_nbits (s_pkey), &data, 1);
+ rc = sexp_data_to_mpi (s_data, gcry_pk_get_nbits (s_pkey), &data, 1,
+ &flags);
if (rc) {
release_mpi_array( pkey );
gcry_free (pkey);
@@ -1276,7 +1297,7 @@ gcry_pk_encrypt (GCRY_SEXP *r_ciph, GCRY_SEXP s_data, GCRY_SEXP s_pkey)
/* Now we can encrypt data to ciph */
ciph = gcry_xcalloc( (strlen(algo_elems)+1) , sizeof *ciph );
- rc = pubkey_encrypt( algo, ciph, data, pkey );
+ rc = pubkey_encrypt( algo, ciph, data, pkey, flags );
release_mpi_array( pkey );
gcry_free (pkey); pkey = NULL;
mpi_free( data );
@@ -1289,14 +1310,20 @@ gcry_pk_encrypt (GCRY_SEXP *r_ciph, GCRY_SEXP s_data, GCRY_SEXP s_pkey)
/* We did it. Now build the return list */
{
char *string, *p;
- size_t nelem, needed= strlen(algo_name) + 20;
+ size_t nelem, needed= strlen(algo_name) + 30;
+
+ /* FIXME, this calculation needs to be cleaned up.
+ -moritz */
/* count elements, so that we can allocate enough space */
for(nelem=0; algo_elems[nelem]; nelem++ )
needed += 10; /* 6 + a safety margin */
/* build the string */
string = p = gcry_xmalloc ( needed );
- p = stpcpy ( p, "(enc-val(" );
+ p = stpcpy ( p, "(enc-val(flags " );
+ if (flags & PUBKEY_FLAG_NO_BLINDING)
+ p = stpcpy (p, "no-blinding");
+ p = stpcpy (p, ")(");
p = stpcpy ( p, algo_name );
for(i=0; algo_elems[i]; i++ ) {
*p++ = '(';
@@ -1366,14 +1393,15 @@ int
gcry_pk_decrypt( GCRY_SEXP *r_plain, GCRY_SEXP s_data, GCRY_SEXP s_skey )
{
MPI *skey, *data, plain;
- int rc, algo, dataalgo, modern, want_pkcs1;
-
+ int rc, algo, dataalgo, modern, want_pkcs1, flags;
+
*r_plain = NULL;
rc = sexp_to_key( s_skey, 1, &skey, &algo, NULL );
if( rc ) {
return rc;
}
- rc = sexp_to_enc( s_data, &data, &dataalgo, &modern, &want_pkcs1 );
+ rc = sexp_to_enc( s_data, &data, &dataalgo, &modern, &want_pkcs1,
+ &flags );
if( rc ) {
release_mpi_array( skey );
gcry_free (skey);
@@ -1387,7 +1415,7 @@ gcry_pk_decrypt( GCRY_SEXP *r_plain, GCRY_SEXP s_data, GCRY_SEXP s_skey )
return GCRYERR_CONFLICT; /* key algo does not match data algo */
}
- rc = pubkey_decrypt( algo, &plain, data, skey );
+ rc = pubkey_decrypt( algo, &plain, data, skey, flags );
if( rc ) {
release_mpi_array( skey );
gcry_free (skey);
@@ -1473,7 +1501,7 @@ gcry_pk_sign( GCRY_SEXP *r_sig, GCRY_SEXP s_hash, GCRY_SEXP s_skey )
/* get the stuff we want to sign */
/* Note that pk_get_nbits does also work on a private key */
- rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_skey), &hash, 0);
+ rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_skey), &hash, 0, NULL);
if (rc) {
release_mpi_array( skey );
gcry_free (skey);
@@ -1571,7 +1599,7 @@ gcry_pk_verify( GCRY_SEXP s_sig, GCRY_SEXP s_hash, GCRY_SEXP s_pkey )
return GCRYERR_CONFLICT; /* algo does not match */
}
- rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_pkey), &hash, 0);
+ rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_pkey), &hash, 0, 0);
if (rc) {
release_mpi_array( pkey );
gcry_free (pkey);
diff --git a/cipher/rsa.c b/cipher/rsa.c
index 9514a065..57aedaf1 100644
--- a/cipher/rsa.c
+++ b/cipher/rsa.c
@@ -432,7 +432,8 @@ _gcry_rsa_check_secret_key( int algo, MPI *skey )
int
-_gcry_rsa_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
+_gcry_rsa_encrypt (int algo, MPI *resarr, MPI data, MPI *pkey,
+ int flags)
{
RSA_public_key pk;
@@ -446,22 +447,123 @@ _gcry_rsa_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
return 0;
}
+/* Perform RSA blinding. */
+GcryMPI
+_gcry_rsa_blind (MPI x, MPI r, MPI e, MPI n)
+{
+ /* A helper. */
+ GcryMPI a;
+
+ /* Result. */
+ GcryMPI 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. */
+GcryMPI
+_gcry_rsa_unblind (MPI x, MPI ri, MPI n)
+{
+ GcryMPI 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;
+}
+
int
-_gcry_rsa_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
+_gcry_rsa_decrypt (int algo, MPI *result, MPI *data, MPI *skey,
+ int flags)
{
RSA_secret_key sk;
-
- if( algo != 1 && algo != 2 )
+ GcryMPI r = MPI_NULL; /* Random number needed for
+ blinding. */
+ GcryMPI ri = MPI_NULL; /* Modular multiplicative inverse of
+ r. */
+ GcryMPI x = MPI_NULL; /* Data to decrypt. */
+ GcryMPI y; /* Result. */
+
+ if (algo != 1 && algo != 2)
return GCRYERR_INV_PK_ALGO;
+ /* Extract private key. */
sk.n = skey[0];
sk.e = skey[1];
sk.d = skey[2];
sk.p = skey[3];
sk.q = skey[4];
sk.u = skey[5];
- *result = mpi_alloc_secure( mpi_get_nlimbs( sk.n ) );
- secret( *result, data[0], &sk );
+
+ y = gcry_mpi_snew (gcry_mpi_get_nbits (sk.n));
+
+ 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). */
+ 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_STRONG_RANDOM);
+ gcry_mpi_mod (r, r, sk.n);
+
+ /* Actually it should be okay to skip the check for equality
+ with either p or q here. */
+
+ /* Calculate inverse of r. */
+ if (! gcry_mpi_invm (ri, r, sk.n))
+ BUG ();
+ }
+
+ if (! (flags & PUBKEY_FLAG_NO_BLINDING))
+ /* Do blinding. */
+ x = _gcry_rsa_blind (data[0], r, sk.e, sk.n);
+ else
+ /* Skip blinding. */
+ x = data[0];
+
+ /* Do the encryption. */
+ secret (y, x, &sk);
+
+ if (! (flags & PUBKEY_FLAG_NO_BLINDING))
+ {
+ /* Undo blinding. */
+ GcryMPI a = gcry_mpi_copy (y);
+
+ gcry_mpi_release (y);
+ y = _gcry_rsa_unblind (a, ri, sk.n);
+ }
+
+ 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 0;
}
diff --git a/cipher/rsa.h b/cipher/rsa.h
index 8bd77f66..58be7a3f 100644
--- a/cipher/rsa.h
+++ b/cipher/rsa.h
@@ -24,8 +24,8 @@
int _gcry_rsa_generate( int algo, unsigned int nbits, unsigned long use_e,
MPI *skey, MPI **retfactors );
int _gcry_rsa_check_secret_key( int algo, MPI *skey );
-int _gcry_rsa_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey );
-int _gcry_rsa_decrypt( int algo, MPI *result, MPI *data, MPI *skey );
+int _gcry_rsa_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey, int flags);
+int _gcry_rsa_decrypt( int algo, MPI *result, MPI *data, MPI *skey, int flags);
int _gcry_rsa_sign( int algo, MPI *resarr, MPI data, MPI *skey );
int _gcry_rsa_verify( int algo, MPI hash, MPI *data, MPI *pkey,
int (*cmp)(void *, MPI), void *opaquev );