Commit 92cd2555 authored by Werner Koch's avatar Werner Koch

See ChangeLog: Fri Jul 14 19:38:23 CEST 2000 Werner Koch

parent d1648b4d
Fri Jul 14 19:38:23 CEST 2000 Werner Koch <wk@>
The big merge between this one and the stable branch 1.0. Still need
to merge TNANKS, AUTHORS and such. It probaly does not compile yet.
* acinclude.m4 (GNUPG_CHECK_MLOCK): Fixed syntax error in C code.
* configure.in: Add check for termio.h, wait unctiosn and sigaction.
* acinclude.m4, configure.in (GNUPG_CHECK_GNUMAKE): New.
* acinclude.m4 (MKDIR_TAKES_ONE_ARG): Check some headers. By Gal Quri.
* configure.in (AM_INIT_AUTOMAKE): Use this now. By Gal.
* acinclude.m4 (GNUPG_CHECK_EXPORTDYNAMIC): Replacement for
GNUPG_CHECK_RDYNAMIC which should handle gcc with non GNU ld nicer.
Contributed by Dave Dykstra.
* configure.in (GNYPG_CHECK_RDYNAMIC): Replaced by the new check.
* configure.in: Add a test for unisgned long long.
* configure.in (DYNLINK_MOD_CFLAGS): Set different for NetBSD.
* configure.in: Add check for clock_gettime
* configure.in (ALL_LINGUAS): Add nl.
* configure.in (ALL_LINGUAS): Add Esperanto.
* configure.in (ALL_LINGUAS): Add sv and ja.
* configure.in: Use /usr/local for CFLAGS and LDFLAGS when
target is freebsd. By Rmi.
* configure.in: Do not set development version when the version has
a dash in it. Suggested by Dave Dykstra.
* configure.in: Removed substitution for doc/gph/Makefile.
Do all the gcc warning only in maintainer mode.
* configure.in (dlopen): Use CHECK_FUNC for a test of dlopen in libc.
Suggested by Alexandre Oliva.
(-Wall): Moved the settting of gcc warning options near to the end
so that tests don't get confused. Suggested by Paul D. Smith.
* acinclude.m4 (GNUPG_SYS_NM_PARSE): Added BSDI support.
(GNUPG_CHECK_RDYNAMIC): Ditto.
* acinclude.m4 (GNUPG_CHECK_MLOCK): Changed the way to test for
librt. Test suggested by Jeff Long.
* acinclude.m4 (GNUPG_CHECK_MLOCK): Do librt check only when
we can't link a test program. This way GNU systems don't need
to link against linrt.
(GNUPG_CHECK_IPC): Fixed use of TRY_COMPILE macro. From Tim Mooney.
* acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Add support for
DJGPP.
(GNUPG_CHECK_MLOCK): Check whether mlock sits in librt.
* acinclude.m4 (GNUPG_CHECK_RDYNAMIC): Add NetBSD. By Thomas Klausner.
* acconfig.h (HAVE_MLOCK): Added
Mon Mar 13 19:22:46 CET 2000 Werner Koch <wk@openit.de>
* configure.in: Now uses the Docbook M$s from GPH.
* configure.in: Now uses the Docbook M4s from GPH.
Mon Jan 31 17:46:35 CET 2000 Werner Koch <wk@>
......
......@@ -53,6 +53,8 @@
#undef HAVE_STPCPY
#undef HAVE_MLOCK
#undef BIG_ENDIAN_HOST
#undef LITTLE_ENDIAN_HOST
......
......@@ -50,6 +50,25 @@ AC_DEFUN(GNUPG_FIX_HDR_VERSION,
])
dnl GNUPG_CHECK_GNUMAKE
dnl
AC_DEFUN(GNUPG_CHECK_GNUMAKE,
[
if ${MAKE-make} --version 2>/dev/null | grep '^GNU ' >/dev/null 2>&1; then
:
else
AC_MSG_WARN([[
***
*** It seems that you are not using GNU make. Some make tools have serious
*** flaws and you may not be able to build this software at all. Before you
*** complain, please try GNU make: GNU make is easy to build and available
*** at all GNU archives. It is always available from ftp.gnu.org:/gnu/make.
***]])
fi
])
dnl GNUPG_LINK_FILES( SRC, DEST )
dnl same as AC_LINK_FILES, but collect the files to link in
dnl some special variables and do the link
......@@ -212,39 +231,38 @@ define(GNUPG_CHECK_PIC,
######################################################################
# Check for rdynamic flag
# This sets CFLAGS_RDYNAMIC to the required flags
# Check for export-dynamic flag
# This sets CFLAGS_EXPORTDYNAMIC to the required flags
######################################################################
dnl GNUPG_CHECK_RDYNAMIC
dnl GNUPG_CHECK_EXPORTDYNAMIC
dnl
define(GNUPG_CHECK_RDYNAMIC,
[ AC_MSG_CHECKING(how to specify -rdynamic)
CFLAGS_RDYNAMIC=
define(GNUPG_CHECK_EXPORTDYNAMIC,
[ AC_MSG_CHECKING(how to specify -export-dynamic)
if test "$cross_compiling" = yes; then
AC_MSG_RESULT(assume none)
AC_MSG_RESULT(assume none)
CFLAGS_EXPORTDYNAMIC=""
else
case "$host_os" in
solaris* )
CFLAGS_RDYNAMIC="-Wl,-dy"
;;
hpux* )
CFLAGS_RDYNAMIC="-Wl,-E"
;;
openbsd* | freebsd2* | osf4* | irix* )
CFLAGS_RDYNAMIC=""
;;
* )
CFLAGS_RDYNAMIC="-Wl,-export-dynamic"
;;
esac
AC_MSG_RESULT($CFLAGS_RDYNAMIC)
AC_CACHE_VAL(gnupg_cv_export_dynamic,[
if AC_TRY_COMMAND([${CC-cc} $CFLAGS -Wl,--version 2>&1 |
grep "GNU ld" >/dev/null]); then
# using gnu's linker
gnupg_cv_export_dynamic="-Wl,-export-dynamic"
else
case "$host_os" in
hpux* )
gnupg_cv_export_dynamic="-Wl,-E"
;;
* )
gnupg_cv_export_dynamic=""
;;
esac
fi
])
AC_MSG_RESULT($gnupg_cv_export_dynamic)
CFLAGS_EXPORTDYNAMIC="$gnupg_cv_export_dynamic"
fi
])
#####################################################################
# Check for SysV IPC (from GIMP)
# And see whether we have a SHM_LOCK (FreeBSD does not have it).
......@@ -299,7 +317,8 @@ define(GNUPG_CHECK_IPC,
AC_TRY_COMPILE([#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>],[
int foo( int shm_id ) { shmctl(shm_id, SHM_LOCK, 0); }
int shm_id;
shmctl(shm_id, SHM_LOCK, 0);
],
gnupg_cv_ipc_have_shm_lock="yes",
gnupg_cv_ipc_have_shm_lock="no"
......@@ -318,11 +337,46 @@ define(GNUPG_CHECK_IPC,
######################################################################
# Check whether mlock is broken (hpux 10.20 raises a SIGBUS if mlock
# is not called from uid 0 (not tested whether uid 0 works)
# For DECs Tru64 we have also to check whether mlock is in librt
# mlock is there a macro using memlk()
######################################################################
dnl GNUPG_CHECK_MLOCK
dnl
define(GNUPG_CHECK_MLOCK,
[ AC_CHECK_FUNCS(mlock)
if test "$ac_cv_func_mlock" = "no"; then
AC_CHECK_HEADERS(sys/mman.h)
if test "$ac_cv_header_sys_mman_h" = "yes"; then
# Add librt to LIBS:
AC_CHECK_LIB(rt, memlk)
AC_CACHE_CHECK([whether mlock is in sys/mman.h],
gnupg_cv_mlock_is_in_sys_mman,
[AC_TRY_LINK([
#include <assert.h>
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
], [
int i;
mkdir ("foo", 0);
/* glibc defines this for functions which it implements
* to always fail with ENOSYS. Some functions are actually
* named something starting with __ and the normal name
* is an alias. */
#if defined (__stub_mlock) || defined (__stub___mlock)
choke me
#else
mlock(&i, 4);
#endif
; return 0;
],
gnupg_cv_mlock_is_in_sys_mman=yes,
gnupg_cv_mlock_is_in_sys_mman=no)])
if test "$gnupg_cv_mlock_is_in_sys_mman" = "yes"; then
AC_DEFINE(HAVE_MLOCK)
fi
fi
fi
if test "$ac_cv_func_mlock" = "yes"; then
AC_MSG_CHECKING(whether mlock is broken)
AC_CACHE_VAL(gnupg_cv_have_broken_mlock,
......@@ -372,9 +426,10 @@ define(GNUPG_CHECK_MLOCK,
])
################################################################
################################################################
# GNUPG_PROG_NM - find the path to a BSD-compatible name lister
################################################################
AC_DEFUN(GNUPG_PROG_NM,
[AC_MSG_CHECKING([for BSD-compatible nm])
AC_CACHE_VAL(ac_cv_path_NM,
......@@ -433,7 +488,7 @@ case "$host_os" in
aix*)
ac_symcode='[BCDTU]'
;;
freebsd* | netbsd* | openbsd* | sunos* | cygwin32* | mingw32*)
freebsd* | netbsd* | openbsd* | bsdi* | sunos* | cygwin32* | mingw32*)
ac_sympat='_\([_A-Za-z][_A-Za-z0-9]*\)'
ac_symxfrm='_\1 \1'
;;
......@@ -586,7 +641,7 @@ AC_CHECK_TOOL(AS, as, false)
AC_DEFUN(GNUPG_SYS_SYMBOL_UNDERSCORE,
[tmp_do_check="no"
case "${target}" in
i386-emx-os2 | i[3456]86-pc-os2*emx )
i386-emx-os2 | i[3456]86-pc-os2*emx | i386-pc-msdosdjgpp)
ac_cv_sys_symbol_underscore=yes
;;
*)
......@@ -645,7 +700,8 @@ dnl Stolen from gcc
dnl Define MKDIR_TAKES_ONE_ARG if mkdir accepts only one argument instead
dnl of the usual 2.
AC_DEFUN(GNUPG_FUNC_MKDIR_TAKES_ONE_ARG,
[AC_CACHE_CHECK([if mkdir takes one argument], gnupg_cv_mkdir_takes_one_arg,
[AC_CHECK_HEADERS(sys/stat.h unistd.h direct.h)
AC_CACHE_CHECK([if mkdir takes one argument], gnupg_cv_mkdir_takes_one_arg,
[AC_TRY_COMPILE([
#include <sys/types.h>
#ifdef HAVE_SYS_STAT_H
......@@ -663,7 +719,6 @@ if test $gnupg_cv_mkdir_takes_one_arg = yes ; then
fi
])
dnl GPH_PROG_DOCBOOK()
dnl Check whether we have the needed Docbook environment
dnl and issue a warning if this is not the case.
......
Fri Jul 14 19:38:23 CEST 2000 Werner Koch <wk@>
* md.c (gcry_md_ctl): Support GCRYCTL_{START,STOP}_DUMP.
* Makefile.am: Never compile mingw32 as module.
* Makefile.am: Tweaked module build and removed libtool
* Makefile.am: Replaced -O1 by -O. Suggested by Alec Habig.
* elgamal.c (sign): Removed inactive code.
* rsa.c, rsa.h: New based on the old module version (only in CVS for now).
* pubkey.c (setup_pubkey_table): Added commented support for RSA.
* rndunix.c (waitpid): New. For UTS 2.1. All by Dave Dykstra.
(my_popen): Do the FD_CLOEXEC only if it is available
(start_gatherer): Cope with missing _SC_OPEN_MAX
* rndunix.c: Add some more headers for QNX. By Sam Roberts.
* rndegd.c (gather_random): Shortcut level 0.
* rndunix.c (gather_random): Ditto.
* rndw32.c (gather_random): Ditto.
* rndw32.c: Replaced with code from Cryptlib and commented the old stuff.
* rndw32.c: Add some debuging code enabled by an environment variable.
* random.c (read_seed_file): Binary open for DOSish system
(update_random_seed_file): Ditto.
* random.c [MINGW32]: Include process.h for getpid.
* random.c (fast_random_poll): Add clock_gettime() as fallback for
system which support this POSIX.4 fucntion. By Sam Roberts.
* random.c (read_seed_file): Removed the S_ISLNK test becuase it
is already covered by !S_ISREG and is not defined in Unixware.
Reported by Dave Dykstra.
(update_random_seed_file): Silently ignore update request when pool
is not filled.
* random.c (read_seed_file): New.
(set_random_seed_file): New.
(read_pool): Try to read the seeding file.
(update_random_seed_file): New.
(read_pool): Do an initial extra seeding when level 2 quality random
is requested the first time. This requestes at least POOLSIZE/2 bytes
of entropy. Compined with the seeding file this should make normal
random bytes cheaper and increase the quality of the random bytes
used for key generation.
* random.c (read_pool): Print a more friendly error message in
cases when too much random is requested in one call.
* random.c (fast_random_poll): Check whether RUSAGE_SELF is defined;
this is not the case for some ESIX and Unixware, although they have
getrusage().
* primegen.c (generate_elg_prime): All primes are now generated with
the lowest random quality level. Because they are public anyway we
don't need stronger random and by this we do not drain the systems
entropy so much.
* primegen.c (register_primegen_progress): New.
* dsa.c (register_pk_dsa_progress): New.
* elgamal.c (register_pk_elg_progress): New.
* elgamal.c (wiener_map): New.
(gen_k): Use a much smaller k.
(generate): Calculate the qbits using the wiener map and
choose an x at a size comparable to the one choosen in gen_k
* rmd160.c (rmd160_get_info): Moved casting to the left side due to a
problem with UTS4.3. Suggested by Dave Dykstra.
* sha1.c (sha1_get_info): Ditto.
* tiger.c (tiger_get_info): Ditto.
* md5.c (md5_get_info): Ditto
* des.c (des_get_info): Ditto.
* blowfish.c (blowfish_get_info): Ditto.
* cast5.c (cast5_get_info): Ditto.
* twofish.c (twofish_get_info): Ditto.
Fri Mar 24 11:25:45 CET 2000 Werner Koch <wk@openit.de>
* md.c (md_open): Add hmac arg and allocate space for the pads.
......
......@@ -5,15 +5,8 @@ INCLUDES = -I$(top_srcdir)/gcrypt
noinst_LTLIBRARIES = libcipher.la
# The configure script greps the module names from the following lines.
# You must also add all these names to EXTRA_PROGRAMS some lines below
# and EXTRA_foo_SOURCES entries.
# Hmmm is there a more easy way to do this? (EXTRA_PROGRAMS
# might also list programs which are not modules)
# MODULES: rndunix rndlinux rndegd rndw32
# MODULES: sha1 rmd160 md5 tiger
EXTRA_PROGRAMS = rndunix rndlinux rndegd rndw32 \
sha1 rmd160 md5 tiger
# The configure script greps the module names from the EXTRA_PROGRAMS line
EXTRA_PROGRAMS = rndlinux rndunix rndegd rndw32 sha1 rmd160 md5 tiger
EXTRA_rndlinux_SOURCES = rndlinux.c
EXTRA_rndunix_SOURCES = rndunix.c
......@@ -73,7 +66,7 @@ libcipher_la_LIBADD = @STATIC_CIPHER_OBJS@
tiger: $(srcdir)/tiger.c
`echo $(COMPILE) $(DYNLINK_MOD_CFLAGS) -o tiger $(srcdir)/tiger.c | \
sed -e 's/-O[2-9s]*/-O1/g' `
sed -e 's/-O[2-9s]*/-O/g' `
tiger.o: $(srcdir)/tiger.c
`echo $(COMPILE) -c $(srcdir)/tiger.c | sed -e 's/-O[2-9s]*/-O1/g' `
......@@ -98,9 +91,3 @@ rndlinux: $(srcdir)/rndlinux.c
rndegd: $(srcdir)/rndegd.c
$(COMPILE) $(DYNLINK_MOD_CFLAGS) -o rndegd $(srcdir)/rndegd.c
# We need to have a better system for selection which modules
# to compile. For now this works.
rndw32: $(srcdir)/rndw32.c
echo "#!/bin/sh" >rndw32
echo "Not usable as a module" >>rndw32
......@@ -584,9 +584,12 @@ blowfish_get_info( int algo, size_t *keylen,
*keylen = 128;
*blocksize = BLOWFISH_BLOCKSIZE;
*contextsize = sizeof(BLOWFISH_context);
*r_setkey = FNCCAST_SETKEY(bf_setkey);
*r_encrypt= FNCCAST_CRYPT(encrypt_block);
*r_decrypt= FNCCAST_CRYPT(decrypt_block);
*(int (**)(BLOWFISH_context*, byte*, unsigned))r_setkey
= bf_setkey;
*(void (**)(BLOWFISH_context*, byte*, byte*))r_encrypt
= encrypt_block;
*(void (**)(BLOWFISH_context*, byte*, byte*))r_decrypt
= decrypt_block;
if( algo == CIPHER_ALGO_BLOWFISH )
return "BLOWFISH";
......
......@@ -610,9 +610,13 @@ cast5_get_info( int algo, size_t *keylen,
*keylen = 128;
*blocksize = CAST5_BLOCKSIZE;
*contextsize = sizeof(CAST5_context);
*r_setkey = FNCCAST_SETKEY(cast_setkey);
*r_encrypt= FNCCAST_CRYPT(encrypt_block);
*r_decrypt= FNCCAST_CRYPT(decrypt_block);
*(int (**)(CAST5_context*, byte*, unsigned))r_setkey
= cast_setkey;
*(void (**)(CAST5_context*, byte*, byte*))r_encrypt
= encrypt_block;
*(void (**)(CAST5_context*, byte*, byte*))r_decrypt
= decrypt_block;
if( algo == CIPHER_ALGO_CAST5 )
return "CAST5";
......
......@@ -1001,9 +1001,12 @@ des_get_info( int algo, size_t *keylen,
*keylen = 192;
*blocksize = 8;
*contextsize = sizeof(struct _tripledes_ctx);
*r_setkey = FNCCAST_SETKEY(do_tripledes_setkey);
*r_encrypt= FNCCAST_CRYPT(do_tripledes_encrypt);
*r_decrypt= FNCCAST_CRYPT(do_tripledes_decrypt);
*(int (**)(struct _tripledes_ctx*, byte*, unsigned))r_setkey
= do_tripledes_setkey;
*(void (**)(struct _tripledes_ctx*, byte*, byte*))r_encrypt
= do_tripledes_encrypt;
*(void (**)(struct _tripledes_ctx*, byte*, byte*))r_decrypt
= do_tripledes_decrypt;
return "3DES";
}
return NULL;
......
/* dsa.c - DSA signature scheme
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
......@@ -52,13 +52,28 @@ static void generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors );
static void sign(MPI r, MPI s, MPI input, DSA_secret_key *skey);
static int verify(MPI r, MPI s, MPI input, DSA_public_key *pkey);
static void (*progress_cb) ( void *, int );
static void *progress_cb_data;
void
register_pk_dsa_progress ( void (*cb)( void *, int), void *cb_data )
{
progress_cb = cb;
progress_cb_data = cb_data;
}
static void
progress( int c )
{
fputc( c, stderr );
if ( progress_cb )
progress_cb ( progress_cb_data, c );
else
fputc( c, stderr );
}
/****************
* Generate a random secret exponent k less than q
*/
......
/* elgamal.c - ElGamal Public Key encryption
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
*
* For a description of the algorithm, see:
* Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
......@@ -56,13 +56,67 @@ static void sign(MPI a, MPI b, MPI input, ELG_secret_key *skey);
static int verify(MPI a, MPI b, MPI input, ELG_public_key *pkey);
static void (*progress_cb) ( void *, int );
static void *progress_cb_data;
void
register_pk_elg_progress ( void (*cb)( void *, int), void *cb_data )
{
progress_cb = cb;
progress_cb_data = cb_data;
}
static void
progress( int c )
{
fputc( c, stderr );
if ( progress_cb )
progress_cb ( progress_cb_data, c );
else
fputc( c, stderr );
}
/****************
* Michael Wiener's table on subgroup sizes to match field sizes
* (floating around somewhere - Fixme: need a reference)
*/
static unsigned int
wiener_map( unsigned int n )
{
static struct { unsigned int p_n, q_n; } t[] =
{ /* p q attack cost */
{ 512, 119 }, /* 9 x 10^17 */
{ 768, 145 }, /* 6 x 10^21 */
{ 1024, 165 }, /* 7 x 10^24 */
{ 1280, 183 }, /* 3 x 10^27 */
{ 1536, 198 }, /* 7 x 10^29 */
{ 1792, 212 }, /* 9 x 10^31 */
{ 2048, 225 }, /* 8 x 10^33 */
{ 2304, 237 }, /* 5 x 10^35 */
{ 2560, 249 }, /* 3 x 10^37 */
{ 2816, 259 }, /* 1 x 10^39 */
{ 3072, 269 }, /* 3 x 10^40 */
{ 3328, 279 }, /* 8 x 10^41 */
{ 3584, 288 }, /* 2 x 10^43 */
{ 3840, 296 }, /* 4 x 10^44 */
{ 4096, 305 }, /* 7 x 10^45 */
{ 4352, 313 }, /* 1 x 10^47 */
{ 4608, 320 }, /* 2 x 10^48 */
{ 4864, 328 }, /* 2 x 10^49 */
{ 5120, 335 }, /* 3 x 10^50 */
{ 0, 0 }
};
int i;
for(i=0; t[i].p_n; i++ ) {
if( n <= t[i].p_n )
return t[i].q_n;
}
/* not in table - use some arbitrary high number ;-) */
return n / 8 + 200;
}
static void
test_keys( ELG_secret_key *sk, unsigned nbits )
{
......@@ -104,38 +158,44 @@ gen_k( MPI p )
MPI k = mpi_alloc_secure( 0 );
MPI temp = mpi_alloc( mpi_get_nlimbs(p) );
MPI p_1 = mpi_copy(p);
unsigned int nbits = mpi_get_nbits(p);
unsigned int nbytes = (nbits+7)/8;
unsigned int orig_nbits = mpi_get_nbits(p);
unsigned int nbits, nbytes;
char *rndbuf = NULL;
/* IMO using a k much lesser than p is sufficient and it greatly
* improves the encryption performance. We use Wiener's table
* and add a large safety margin.
*/
nbits = wiener_map( orig_nbits ) * 3 / 2;
if( nbits >= orig_nbits )
BUG();
nbytes = (nbits+7)/8;
if( DBG_CIPHER )
log_debug("choosing a random k ");
mpi_sub_ui( p_1, p, 1);
for(;;) {
if( DBG_CIPHER )
progress('.');
if( !rndbuf || nbits < 32 ) {
g10_free(rndbuf);
rndbuf = gcry_random_bytes_secure( nbytes, GCRY_STRONG_RANDOM );
}
else { /* change only some of the higher bits */
/* we could imporove this by directly requesting more memory
/* we could improve this by directly requesting more memory
* at the first call to get_random_bytes() and use this the here
* maybe it is easier to do this directly in random.c */
* maybe it is easier to do this directly in random.c
* Anyway, it is highly inlikely that we will ever reach this code
*/
char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM );
memcpy( rndbuf, pp, 4 );
g10_free(pp);
log_debug("gen_k: tsss, never expected to reach this\n");
}
mpi_set_buffer( k, rndbuf, nbytes, 0 );
for(;;) {
/* make sure that the number is of the exact lenght */
if( mpi_test_bit( k, nbits-1 ) )
mpi_set_highbit( k, nbits-1 );
else {
mpi_set_highbit( k, nbits-1 );
mpi_clear_bit( k, nbits-1 );
}
/* Hmm, actually we don't need this step here
* because we use k much smaller than p - we do it anyway
* just in case the keep on adding a one to k ;) */
if( !(mpi_cmp( k, p_1 ) < 0) ) { /* check: k < (p-1) */
if( DBG_CIPHER )
progress('+');
......@@ -149,6 +209,8 @@ gen_k( MPI p )
if( mpi_gcd( temp, k, p_1 ) )
goto found; /* okay, k is relatively prime to (p-1) */
mpi_add_ui( k, k, 1 );
if( DBG_CIPHER )
progress('.');
}
}
found:
......@@ -167,7 +229,7 @@ gen_k( MPI p )
* and an array with n-1 factors of (p-1)
*/
static void
generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors )
generate( ELG_secret_key *sk, unsigned int nbits, MPI **ret_factors )
{
MPI p; /* the prime */
MPI p_min1;
......@@ -175,19 +237,15 @@ generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors )
MPI x; /* the secret exponent */
MPI y;
MPI temp;
unsigned qbits;
unsigned int qbits;
unsigned int xbits;
byte *rndbuf;
p_min1 = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
temp = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
if( nbits < 512 )
qbits = 120;
else if( nbits <= 1024 )
qbits = 160;
else if( nbits <= 2048 )
qbits = 200;
else
qbits = 240;
qbits = wiener_map( nbits );
if( qbits & 1 ) /* better have a even one */
qbits++;
g = mpi_alloc(1);
p = generate_elg_prime( 0, nbits, qbits, g, ret_factors );
mpi_sub_ui(p_min1, p, 1);
......@@ -198,18 +256,26 @@ generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors )
* This must be a very good random number because this is the
* secret part. The prime is public and may be shared anyway,
* so a random generator level of 1 is used for the prime.
*
* I don't see a reason to have a x of about the same size
* as the p. It should be sufficient to have one about the size
* of q or the later used k plus a large safety margin. Decryption
* will be much faster with such an x.
*/
x = mpi_alloc_secure( nbits/BITS_PER_MPI_LIMB );
xbits = qbits * 3 / 2;
if( xbits >= nbits )
BUG();
x = mpi_alloc_secure( xbits/BITS_PER_MPI_LIMB );
if( DBG_CIPHER )
log_debug("choosing a random x ");
log_debug("choosing a random x of size %u", xbits );
rndbuf = NULL;
do {
if( DBG_CIPHER )
progress('.');
if( rndbuf ) { /* change only some of the higher bits */
if( nbits < 16 ) {/* should never happen ... */
if( xbits < 16 ) {/* should never happen ... */
g10_free(rndbuf);
rndbuf = gcry_random_bytes_secure( (nbits+7)/8,
rndbuf = gcry_random_bytes_secure( (xbits+7)/8,
GCRY_VERY_STRONG_RANDOM );
}
else {
......@@ -220,11 +286,11 @@ generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors )
}
}
else {
rndbuf = gcry_random_bytes_secure( (nbits+7)/8,
rndbuf = gcry_random_bytes_secure( (xbits+7)/8,
GCRY_VERY_STRONG_RANDOM );
}
mpi_set_buffer( x, rndbuf, (nbits+7)/8, 0 );
mpi_clear_highbit( x, nbits+1 );
mpi_set_buffer( x, rndbuf, (xbits+7)/8, 0 );
mpi_clear_highbit( x, xbits+1 );
} while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, p_min1 )<0 ) );
g10_free(rndbuf);
......@@ -311,7 +377,6 @@ decrypt(MPI output, MPI a, MPI b, ELG_secret_key *skey )
MPI t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) );
/* output = b/(a^x) mod p */
gcry_mpi_powm( t1, a, skey->x, skey->p );
mpi_invm( t1, t1, skey->p );
mpi_mulm( output, b, t1, skey->p );
......@@ -351,10 +416,6 @@ sign(MPI a, MPI b, MPI input, ELG_secret_key *skey )
gcry_mpi_powm( a, skey->g, k, skey->p );
mpi_mul(t, skey->x, a );
mpi_subm(t, input, t, p_1 );
while( mpi_is_neg(t) ) {
BUG(); /* That is nonsense code - left over from a very early test?*/
mpi_add(t, t, p_1);
}
mpi_invm(inv, k, p_1 );
mpi_mulm(b, t, inv, p_1 );
......@@ -557,7 +618,7 @@ elg_verify( int algo, MPI hash, MPI *data, MPI *pkey,
unsigned
unsigned int
elg_get_nbits( int algo, MPI *pkey )
{
if( !is_ELGAMAL(algo) )
......@@ -587,10 +648,10 @@ elg_get_info( int algo, int *npkey, int *nskey, int *nenc, int *nsig,
*nsig = 2;