diff options
-rw-r--r-- | cipher/ChangeLog | 17 | ||||
-rw-r--r-- | cipher/dsa.c | 3 | ||||
-rw-r--r-- | cipher/dsa.h | 3 | ||||
-rw-r--r-- | cipher/dynload.c | 6 | ||||
-rw-r--r-- | cipher/dynload.h | 3 | ||||
-rw-r--r-- | cipher/elgamal.c | 3 | ||||
-rw-r--r-- | cipher/elgamal.h | 3 | ||||
-rw-r--r-- | cipher/pubkey.c | 80 | ||||
-rw-r--r-- | cipher/rsa.c | 41 | ||||
-rw-r--r-- | cipher/rsa.h | 3 |
10 files changed, 115 insertions, 47 deletions
diff --git a/cipher/ChangeLog b/cipher/ChangeLog index dac938b0..c6f1fff0 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,3 +1,20 @@ +2003-01-23 Werner Koch <wk@gnupg.org> + + * rsa.c (generate): New arg USE_E to request a specific public + exponent. + (_gcry_rsa_generate): Ditto. + * elgamal.c (_gcry_elg_generate): Must add an dummy argument + instead of USE_E. + * dsa.c (_gcry_dsa_generate): Ditto. + * pubkey.c (dummy_generate): Ditto. + (pubkey_generate): Add USE_E arg and pass it down. + (gcry_pk_genkey): Detect "rsa-use-e" parameter and pass it to generate. + + * pubkey.c (sexp_to_enc): New arg RET_MODERN. + (gcry_pk_decrypt): Make use of it to return a real S-expression. + Return better error codes. + (gcry_pk_verify): Return better error codes. + 2003-01-21 Werner Koch <wk@gnupg.org> * random.c (gcry_random_add_bytes): Add QUALITY argument, let diff --git a/cipher/dsa.c b/cipher/dsa.c index d8ec37bd..61d0c377 100644 --- a/cipher/dsa.c +++ b/cipher/dsa.c @@ -356,7 +356,8 @@ verify(MPI r, MPI s, MPI hash, DSA_public_key *pkey ) *********************************************/ int -_gcry_dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ) +_gcry_dsa_generate( int algo, unsigned nbits, unsigned long dummy, + MPI *skey, MPI **retfactors ) { DSA_secret_key sk; diff --git a/cipher/dsa.h b/cipher/dsa.h index ce8acda3..6789ec6e 100644 --- a/cipher/dsa.h +++ b/cipher/dsa.h @@ -20,7 +20,8 @@ #ifndef G10_DSA_H #define G10_DSA_H -int _gcry_dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ); +int _gcry_dsa_generate( int algo, unsigned int nbits, unsigned long dummy, + MPI *skey, MPI **retfactors ); int _gcry_dsa_check_secret_key( int algo, MPI *skey ); int _gcry_dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey ); int _gcry_dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey, diff --git a/cipher/dynload.c b/cipher/dynload.c index 711468af..4f00a1e7 100644 --- a/cipher/dynload.c +++ b/cipher/dynload.c @@ -218,7 +218,8 @@ _gcry_enum_gnupgext_ciphers( void **enum_context, int *algo, const char * _gcry_enum_gnupgext_pubkeys( void **enum_context, int *algo, int *npkey, int *nskey, int *nenc, int *nsig, int *use, - int (**generate)( int algo, unsigned nbits, MPI *skey, MPI **retfactors ), + 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 ), @@ -230,7 +231,8 @@ _gcry_enum_gnupgext_pubkeys( void **enum_context, int *algo, EXTLIST r; ENUMCONTEXT *ctx; const char * (*finfo)( int, int *, int *, int *, int *, int *, - int (**)( int, unsigned, MPI *, MPI **), + int (**)( int, unsigned int, unsigned long, + MPI *, MPI **), int (**)( int, MPI * ), int (**)( int, MPI *, MPI , MPI * ), int (**)( int, MPI *, MPI *, MPI * ), diff --git a/cipher/dynload.h b/cipher/dynload.h index 9c89cc08..9258352d 100644 --- a/cipher/dynload.h +++ b/cipher/dynload.h @@ -46,7 +46,8 @@ _gcry_enum_gnupgext_ciphers( void **enum_context, int *algo, const char * _gcry_enum_gnupgext_pubkeys( void **enum_context, int *algo, int *npkey, int *nskey, int *nenc, int *nsig, int *use, - int (**generate)( int algo, unsigned nbits, MPI *skey, MPI **retfactors ), + 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 ), diff --git a/cipher/elgamal.c b/cipher/elgamal.c index d982c6a3..ea3a8dd6 100644 --- a/cipher/elgamal.c +++ b/cipher/elgamal.c @@ -498,7 +498,8 @@ verify(MPI a, MPI b, MPI input, ELG_public_key *pkey ) *********************************************/ int -_gcry_elg_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ) +_gcry_elg_generate( int algo, unsigned nbits, unsigned long dummy, + MPI *skey, MPI **retfactors ) { ELG_secret_key sk; diff --git a/cipher/elgamal.h b/cipher/elgamal.h index f1920229..ae9f296a 100644 --- a/cipher/elgamal.h +++ b/cipher/elgamal.h @@ -20,7 +20,8 @@ #ifndef G10_ELGAMAL_H #define G10_ELGAMAL_H -int _gcry_elg_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ); +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 ); diff --git a/cipher/pubkey.c b/cipher/pubkey.c index 0fb6113b..d0a493de 100644 --- a/cipher/pubkey.c +++ b/cipher/pubkey.c @@ -45,7 +45,8 @@ struct pubkey_table_s { int nenc; int nsig; int use; - int (*generate)( int algo, unsigned nbits, MPI *skey, MPI **retfactors ); + 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 ); @@ -111,7 +112,8 @@ static int pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey, int (*cmp)(void *, MPI), void *opaque ); static int -dummy_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ) +dummy_generate( int algo, unsigned int nbits, unsigned long dummy, + MPI *skey, MPI **retfactors ) { log_bug("no generate() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; } static int @@ -488,14 +490,15 @@ pubkey_get_nenc( int algo ) static int -pubkey_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ) +pubkey_generate( int algo, unsigned int nbits, unsigned long use_e, + MPI *skey, MPI **retfactors ) { int i; do { for(i=0; pubkey_table[i].name; i++ ) if( pubkey_table[i].algo == algo ) - return (*pubkey_table[i].generate)( algo, nbits, + return (*pubkey_table[i].generate)( algo, nbits, use_e, skey, retfactors ); } while( load_pubkey_modules() ); return GCRYERR_INV_PK_ALGO; @@ -860,9 +863,11 @@ sexp_to_sig( GCRY_SEXP sexp, MPI **retarray, int *retalgo) * ... * (<param_namen> <mpi>) * )) + * RET_MODERN is set to true when at least an empty flags list has been found. */ static int -sexp_to_enc( GCRY_SEXP sexp, MPI **retarray, int *retalgo, int *ret_want_pkcs1) +sexp_to_enc( GCRY_SEXP sexp, MPI **retarray, int *retalgo, + int *ret_modern, int *ret_want_pkcs1) { GCRY_SEXP list, l2; const char *name; @@ -874,6 +879,7 @@ sexp_to_enc( GCRY_SEXP sexp, MPI **retarray, int *retalgo, int *ret_want_pkcs1) GCRY_MPI *array; *ret_want_pkcs1 = 0; + *ret_modern = 0; /* check that the first element is valid */ list = gcry_sexp_find_token( sexp, "enc-val" , 0 ); if( !list ) @@ -893,6 +899,7 @@ sexp_to_enc( GCRY_SEXP sexp, MPI **retarray, int *retalgo, int *ret_want_pkcs1) /* There is a flags element - process it */ const char *s; + *ret_modern = 1; for (i=gcry_sexp_length (l2)-1; i > 0; i--) { s = gcry_sexp_nth_data (l2, i, &n); @@ -1335,34 +1342,38 @@ gcry_pk_encrypt (GCRY_SEXP *r_ciph, GCRY_SEXP s_data, GCRY_SEXP s_pkey) /**************** * Do a PK decrypt operation * - * Caller has to provide a secret key as the SEXP skey and data in a format - * as created by gcry_pk_encrypt. Currently the function returns - * simply a MPI. Later versions of this functions may return a more - * complex data structure. - * + * Caller has to provide a secret key as the SEXP skey and data in a + * format as created by gcry_pk_encrypt. For historic reasons the + * function returns simply an MPI as an S-expression part; this is + * deprecated and the new method should be used which returns a real + * S-expressionl this is selected by adding at least an empt flags + * list to S_DATA. + * * Returns: 0 or an errorcode. * * s_data = (enc-val + * [(flags)] * (<algo> * (<param_name1> <mpi>) * ... * (<param_namen> <mpi>) * )) * s_skey = <key-as-defined-in-sexp_to_key> - * r_plain= (<mpi>) FIXME: Return a more structered value - */ + * r_plain= Either an incomplete S-expression without the parentheses + * or if the flags list is used (even if empty) a real S-expression: + * (value PLAIN). */ int gcry_pk_decrypt( GCRY_SEXP *r_plain, GCRY_SEXP s_data, GCRY_SEXP s_skey ) { MPI *skey, *data, plain; - int rc, algo, dataalgo, want_pkcs1; + int rc, algo, dataalgo, modern, want_pkcs1; *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, &want_pkcs1 ); + rc = sexp_to_enc( s_data, &data, &dataalgo, &modern, &want_pkcs1 ); if( rc ) { release_mpi_array( skey ); gcry_free (skey); @@ -1373,7 +1384,7 @@ gcry_pk_decrypt( GCRY_SEXP *r_plain, GCRY_SEXP s_data, GCRY_SEXP s_skey ) gcry_free (skey); release_mpi_array( data ); gcry_free (data); - return -1; /* fixme: add real errornumber - algo does not match */ + return GCRYERR_CONFLICT; /* key algo does not match data algo */ } rc = pubkey_decrypt( algo, &plain, data, skey ); @@ -1382,11 +1393,18 @@ gcry_pk_decrypt( GCRY_SEXP *r_plain, GCRY_SEXP s_data, GCRY_SEXP s_skey ) gcry_free (skey); release_mpi_array( data ); gcry_free (data); - return -1; /* fixme: add real errornumber - decryption failed */ + return GCRYERR_GENERAL; /* decryption failed */ } - if ( gcry_sexp_build( r_plain, NULL, "%m", plain ) ) + if (!modern) { + if ( gcry_sexp_build( r_plain, NULL, "%m", plain ) ) BUG (); + } + else { + if ( gcry_sexp_build( r_plain, NULL, "(value %m)", plain ) ) + BUG (); + } + mpi_free( plain ); release_mpi_array( data ); @@ -1550,7 +1568,7 @@ gcry_pk_verify( GCRY_SEXP s_sig, GCRY_SEXP s_hash, GCRY_SEXP s_pkey ) gcry_free (pkey); release_mpi_array( sig ); gcry_free (sig); - return -1; /* fixme: add real errornumber - algo does not match */ + return GCRYERR_CONFLICT; /* algo does not match */ } rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_pkey), &hash, 0); @@ -1559,7 +1577,7 @@ gcry_pk_verify( GCRY_SEXP s_sig, GCRY_SEXP s_hash, GCRY_SEXP s_pkey ) gcry_free (pkey); release_mpi_array( sig ); gcry_free (sig); - return -1; /* fixme: get a real errorcode for this */ + return rc; } rc = pubkey_verify( algo, hash, sig, pkey, NULL, NULL ); @@ -1647,6 +1665,7 @@ gcry_pk_genkey( GCRY_SEXP *r_key, GCRY_SEXP s_parms ) char sec_elems[20], pub_elems[20]; GCRY_MPI skey[10], *factors; unsigned int nbits; + unsigned long use_e; *r_key = NULL; list = gcry_sexp_find_token( s_parms, "genkey", 0 ); @@ -1688,6 +1707,27 @@ gcry_pk_genkey( GCRY_SEXP *r_key, GCRY_SEXP s_parms ) strcpy( sec_elems, s ); strcat( sec_elems, s2 ); + l2 = gcry_sexp_find_token (list, "rsa-use-e", 0); + if (l2) + { + char buf[50]; + + name = gcry_sexp_nth_data (l2, 1, &n); + if (!name || n >= DIM (buf)-1 ) + { + gcry_sexp_release (l2); + gcry_sexp_release (list); + return GCRYERR_INV_OBJ; /* no value or value too large */ + } + + memcpy (buf, name, n); + buf[n] = 0; + use_e = strtoul (buf, NULL, 0); + gcry_sexp_release (l2); + } + else + use_e = 65537; /* not given, use the value generated by old versions. */ + l2 = gcry_sexp_find_token( list, "nbits", 0 ); gcry_sexp_release ( list ); list = l2; @@ -1707,7 +1747,7 @@ gcry_pk_genkey( GCRY_SEXP *r_key, GCRY_SEXP s_parms ) } gcry_sexp_release ( list ); - rc = pubkey_generate( algo, nbits, skey, &factors ); + rc = pubkey_generate( algo, nbits, use_e, skey, &factors ); if( rc ) { return rc; } diff --git a/cipher/rsa.c b/cipher/rsa.c index 0487b736..a8097be2 100644 --- a/cipher/rsa.c +++ b/cipher/rsa.c @@ -1,6 +1,6 @@ /* rsa.c - RSA function * Copyright (C) 1997, 1998, 1999 by Werner Koch (dd9jn) - * Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. + * Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * @@ -51,7 +51,8 @@ typedef struct { static void test_keys( RSA_secret_key *sk, unsigned nbits ); -static void generate( RSA_secret_key *sk, unsigned nbits ); +static void generate (RSA_secret_key *sk, + unsigned int nbits, unsigned long use_e ); static int check_secret_key( RSA_secret_key *sk ); static void public(MPI output, MPI input, RSA_public_key *skey ); static void secret(MPI output, MPI input, RSA_secret_key *skey ); @@ -83,11 +84,15 @@ test_keys( RSA_secret_key *sk, unsigned nbits ) } /**************** - * Generate a key pair with a key of size NBITS + * Generate a key pair with a key of size NBITS. + * USE_E = 0 let Libcgrypt decide what exponent to use. + * = 1 request the use of a "secure" exponent; this is required by some + * specification to be 65537. + * > 2 Try starting at this value until a working exponent is found. * Returns: 2 structures filled with all needed values */ static void -generate( RSA_secret_key *sk, unsigned nbits ) +generate (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e) { MPI p, q; /* the two primes */ MPI d; /* the private key */ @@ -140,20 +145,17 @@ generate( RSA_secret_key *sk, unsigned nbits ) e=41 0.75 ms e=257 0.95 ms e=65537 1.80 ms - - Note: Due to Sphinx requirements we temorrary change the - exponent until we can rework the interface to provide more - parameters than just the modulus length. */ + */ e = mpi_alloc( (32+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB ); - mpi_set_ui (e, 65537); - if( !gcry_mpi_gcd(t1, e, phi) ) { /* actually never triggered ;-) */ - mpi_set_ui( e, 257); - if( !gcry_mpi_gcd(t1, e, phi) ) { - mpi_set_ui( e, 41); - while( !gcry_mpi_gcd(t1, e, phi) ) /* (while gcd is not 1) */ - mpi_add_ui( e, e, 2); - } - } + if (!use_e) + use_e = 41; /* This is a reasonable secure and fast value */ + else if (use_e == 1) + use_e = 65537; /* A secure value as demanded by Spinx. */ + + use_e |= 1; /* make sure this is odd */ + mpi_set_ui (e, use_e); + while (!gcry_mpi_gcd(t1, e, phi)) /* (while gcd is not 1) */ + mpi_add_ui (e, e, 2); /* calculate the secret key d = e^1 mod phi */ d = gcry_mpi_snew ( nbits ); @@ -350,14 +352,15 @@ secret(MPI output, MPI input, RSA_secret_key *skey ) *********************************************/ int -_gcry_rsa_generate (int algo, unsigned int nbits, MPI *skey, MPI **retfactors) +_gcry_rsa_generate (int algo, unsigned int nbits, unsigned long use_e, + MPI *skey, MPI **retfactors) { RSA_secret_key sk; if( !is_RSA(algo) ) return GCRYERR_INV_PK_ALGO; - generate( &sk, nbits ); + generate( &sk, nbits, use_e ); skey[0] = sk.n; skey[1] = sk.e; skey[2] = sk.d; diff --git a/cipher/rsa.h b/cipher/rsa.h index e709757a..8bd77f66 100644 --- a/cipher/rsa.h +++ b/cipher/rsa.h @@ -21,7 +21,8 @@ #ifndef G10_RSA_H #define G10_RSA_H -int _gcry_rsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ); +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 ); |