summaryrefslogtreecommitdiffstats
path: root/cipher
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2002-08-03 12:50:53 +0200
committerWerner Koch <wk@gnupg.org>2002-08-03 12:50:53 +0200
commit85aa3e18c296cdf18f76a47754d5270eb4e3630e (patch)
treec47a142fce35ba999e72fad2037a8020b3d8ab16 /cipher
parent2002-08-02 Timo Schulz <ts@winpt.org> (diff)
downloadgnupg2-85aa3e18c296cdf18f76a47754d5270eb4e3630e.tar.xz
gnupg2-85aa3e18c296cdf18f76a47754d5270eb4e3630e.zip
The big extension module removal.
Diffstat (limited to 'cipher')
-rw-r--r--cipher/ChangeLog38
-rw-r--r--cipher/Makefile.am72
-rw-r--r--cipher/algorithms.h66
-rw-r--r--cipher/blowfish.h10
-rw-r--r--cipher/cipher.c75
-rw-r--r--cipher/dynload.c606
-rw-r--r--cipher/idea-stub.c187
-rw-r--r--cipher/md.c138
-rw-r--r--cipher/md5.c64
-rw-r--r--cipher/pubkey.c69
-rw-r--r--cipher/rand-internal.h18
-rw-r--r--cipher/random.c42
-rw-r--r--cipher/rmd160.c70
-rw-r--r--cipher/rndegd.c75
-rw-r--r--cipher/rndlinux.c94
-rw-r--r--cipher/rndunix.c77
-rw-r--r--cipher/rndw32.c292
-rw-r--r--cipher/sha1.c70
-rw-r--r--cipher/tiger.c92
19 files changed, 505 insertions, 1650 deletions
diff --git a/cipher/ChangeLog b/cipher/ChangeLog
index 77efc4449..6599a51bc 100644
--- a/cipher/ChangeLog
+++ b/cipher/ChangeLog
@@ -1,3 +1,41 @@
+2002-08-03 Werner Koch <wk@gnupg.org>
+
+ * rndegd.c (do_read): Handle case when read returns 0 to avoid
+ gpg hanging when EGD died. By Christian Biere.
+
+2002-08-02 Werner Koch <wk@gnupg.org>
+
+ The big extension removal.
+
+ * Makefile.am: Removed all extension stuff.
+ * dynload.c: Removed everything except for
+ register_cipher_extension.
+ (dynload_enum_module_names): New.
+ * dynload.h: Removed.
+ * random.c (getfnc_gather_random,getfnc_fast_random_poll):
+ New. Replaced all dynload functions with these ones.
+ * rndunix.c (rndunix_gather_random): Renamed from
+ gather_random. Made global. Removed all dynload stuff.
+ * rndlinux.c (rndlinux_gather_random): Likewise.
+ * rndegd.c (rndegd_gather_random): Likewise.
+ * rndw32.c (rndw32_gather_random)
+ (rndw32_gather_random_fast): Likewise. Also removed the unsued
+ entropy dll code.
+ * md.c (new_list_item): Changed return value to indicate whether
+ an algorithms was loaded.
+ (load_digest_module): Simplified by removing all the dynload code.
+ * algorithms.h: New.
+ * md5.c (md5_get_info): Made global. Removed all dynload stuff.
+ * rmd160.c (rmd160_get_info): Likewise.
+ * sha1.c (sha1_get_info): Likewise.
+ * tiger.c (tiger_get_info): Likewise. Return NULL if we can't use
+ this module.
+ * idea-stub.c: New.
+ * blowfish.h (idea_get_info): Add prototype.
+ * cipher.c (setup_cipher_table): Try to load IDEA.
+ (load_cipher_modules): Removed all dynload code.
+ * pubkey.c (load_pubkey_modules): Removed the dynloading code.
+
2002-07-25 David Shaw <dshaw@jabberwocky.com>
* random.c: "warning" -> "WARNING"
diff --git a/cipher/Makefile.am b/cipher/Makefile.am
index 83e81877e..59aae94d7 100644
--- a/cipher/Makefile.am
+++ b/cipher/Makefile.am
@@ -1,4 +1,4 @@
-# Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+# Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
#
# This file is part of GnuPG.
#
@@ -18,39 +18,14 @@
## Process this file with automake to produce Makefile.in
-
INCLUDES = -I.. -I$(top_srcdir)/include -I$(top_srcdir)/intl
noinst_LIBRARIES = libcipher.a
-# 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
-EXTRA_rndegd_SOURCES = rndegd.c
-EXTRA_rndw32_SOURCES = rndw32.c
-EXTRA_md5_SOURCES = md5.c
-EXTRA_rmd160_SOURCES = rmd160.c
-EXTRA_sha1_SOURCES = sha1.c
-EXTRA_tiger_SOURCES = tiger.c
-
-
-if ENABLE_GNUPG_EXTENSIONS
-pkglib_PROGRAMS = @DYNAMIC_CIPHER_MODS@
-else
-pkglib_PROGRAMS =
-endif
-
-
-DYNLINK_MOD_CFLAGS = -DIS_MODULE @DYNLINK_MOD_CFLAGS@
-
-#libcipher_a_LDFLAGS =
libcipher_a_SOURCES = cipher.c \
pubkey.c \
md.c \
dynload.c \
- dynload.h \
bithelp.h \
des.c \
des.h \
@@ -72,43 +47,22 @@ libcipher_a_SOURCES = cipher.c \
dsa.c \
g10c.c \
smallprime.c \
- construct.c
-
-# configure creates the constructor file
-BUILT_SOURCES = construct.c
-DISTCLEANFILES = construct.c
+ algorithms.h \
+ rndlinux.c \
+ rndunix.c \
+ rndegd.c \
+ rndw32.c \
+ md5.c \
+ rmd160.c \
+ sha1.c \
+ tiger.c
-libcipher_a_DEPENDENCIES = @STATIC_CIPHER_OBJS@
-libcipher_a_LIBADD = @STATIC_CIPHER_OBJS@
+EXTRA_libcipher_a_SOURCES = idea-stub.c
-
-# If I remember it correct, automake 1.4 has a feature to set
-# fooFLAGS depending on the program. So we should check it out.
-
-tiger$(EXEEXT): $(srcdir)/tiger.c
- `echo $(COMPILE) $(DYNLINK_MOD_CFLAGS) -o tiger $(srcdir)/tiger.c | \
- sed -e 's/-O[2-9s]*/-O/g' `
+libcipher_a_DEPENDENCIES = @IDEA_O@
+libcipher_a_LIBADD = @IDEA_O@
tiger.o: $(srcdir)/tiger.c
`echo $(COMPILE) -c $(srcdir)/tiger.c | sed -e 's/-O[2-9s]*/-O1/g' `
-#twofish: $(srcdir)/twofish.c
-# `echo $(COMPILE) $(DYNLINK_MOD_CFLAGS) -o twofish $(srcdir)/twofish.c | \
-# sed -e 's/-O[0-9s]*/ /g' `
-
-twofish: $(srcdir)/twofish.c
- $(COMPILE) $(DYNLINK_MOD_CFLAGS) -o twofish $(srcdir)/twofish.c
-
-#twofish.o: $(srcdir)/twofish.c
-# `echo $(COMPILE) -c $(srcdir)/twofish.c | sed -e 's/-O[0-9s]*/ /g' `
-
-
-rndunix$(EXEEXT): $(srcdir)/rndunix.c
- $(COMPILE) $(DYNLINK_MOD_CFLAGS) -o rndunix $(srcdir)/rndunix.c
-
-rndlinux$(EXEEXT): $(srcdir)/rndlinux.c
- $(COMPILE) $(DYNLINK_MOD_CFLAGS) -o rndlinux $(srcdir)/rndlinux.c
-
-rndegd$(EXEEXT): $(srcdir)/rndegd.c
- $(COMPILE) $(DYNLINK_MOD_CFLAGS) -o rndegd $(srcdir)/rndegd.c
diff --git a/cipher/algorithms.h b/cipher/algorithms.h
new file mode 100644
index 000000000..a6b910612
--- /dev/null
+++ b/cipher/algorithms.h
@@ -0,0 +1,66 @@
+/* algorithms.h - prototypes for algorithm functions.
+ * Copyright (C) 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+#ifndef GNUPG_ALGORITHMS_H
+#define GNUPG_ALGORITHMS_H 1
+
+const char *dynload_enum_module_names (int seq);
+
+
+
+const char *
+md5_get_info (int algo, size_t *contextsize,
+ byte **r_asnoid, int *r_asnlen, int *r_mdlen,
+ void (**r_init)( void *c ),
+ void (**r_write)( void *c, byte *buf, size_t nbytes ),
+ void (**r_final)( void *c ),
+ byte *(**r_read)( void *c )
+ );
+
+
+const char *
+rmd160_get_info (int algo, size_t *contextsize,
+ byte **r_asnoid, int *r_asnlen, int *r_mdlen,
+ void (**r_init)( void *c ),
+ void (**r_write)( void *c, byte *buf, size_t nbytes ),
+ void (**r_final)( void *c ),
+ byte *(**r_read)( void *c )
+ );
+
+const char *
+sha1_get_info (int algo, size_t *contextsize,
+ byte **r_asnoid, int *r_asnlen, int *r_mdlen,
+ void (**r_init)( void *c ),
+ void (**r_write)( void *c, byte *buf, size_t nbytes ),
+ void (**r_final)( void *c ),
+ byte *(**r_read)( void *c )
+ );
+
+const char *
+tiger_get_info (int algo, size_t *contextsize,
+ byte **r_asnoid, int *r_asnlen, int *r_mdlen,
+ void (**r_init)( void *c ),
+ void (**r_write)( void *c, byte *buf, size_t nbytes ),
+ void (**r_final)( void *c ),
+ byte *(**r_read)( void *c )
+ );
+
+
+
+#endif /*GNUPG_ALGORITHMS_H*/
diff --git a/cipher/blowfish.h b/cipher/blowfish.h
index bed034c73..46e302288 100644
--- a/cipher/blowfish.h
+++ b/cipher/blowfish.h
@@ -41,7 +41,7 @@ twofish_get_info( int algo, size_t *keylen,
void (**decryptf)( void *c, byte *outbuf, byte *inbuf )
);
-/* this is just a kludge for the time we have not yet chnaged the cipher
+/* this is just a kludge for the time we have not yet changed the cipher
* stuff to the scheme we use for random and digests */
const char *
rijndael_get_info( int algo, size_t *keylen,
@@ -51,4 +51,12 @@ rijndael_get_info( int algo, size_t *keylen,
void (**decryptf)( void *c, byte *outbuf, byte *inbuf )
);
+const char *
+idea_get_info( int algo, size_t *keylen,
+ size_t *blocksize, size_t *contextsize,
+ int (**setkeyf)( void *c, byte *key, unsigned keylen ),
+ void (**encryptf)( void *c, byte *outbuf, byte *inbuf ),
+ void (**decryptf)( void *c, byte *outbuf, byte *inbuf )
+ );
+
#endif /*G10_BLOWFISH_H*/
diff --git a/cipher/cipher.c b/cipher/cipher.c
index 2744f041a..761ec9b99 100644
--- a/cipher/cipher.c
+++ b/cipher/cipher.c
@@ -1,5 +1,5 @@
/* cipher.c - cipher dispatcher
- * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -30,7 +30,6 @@
#include "des.h"
#include "blowfish.h"
#include "cast5.h"
-#include "dynload.h"
#define MAX_BLOCKSIZE 16
@@ -162,6 +161,16 @@ setup_cipher_table(void)
if( !cipher_table[i].name )
BUG();
i++;
+ cipher_table[i].algo = CIPHER_ALGO_IDEA;
+ cipher_table[i].name = idea_get_info( cipher_table[i].algo,
+ &cipher_table[i].keylen,
+ &cipher_table[i].blocksize,
+ &cipher_table[i].contextsize,
+ &cipher_table[i].setkey,
+ &cipher_table[i].encrypt,
+ &cipher_table[i].decrypt );
+ if (cipher_table[i].name)
+ i++; /* Note that IDEA is usually no available. */
#ifdef IS_DEVELOPMENT_VERSION
cipher_table[i].algo = CIPHER_ALGO_DUMMY;
@@ -186,63 +195,15 @@ setup_cipher_table(void)
static int
load_cipher_modules(void)
{
- static int done = 0;
- static int initialized = 0;
- void *context = NULL;
- struct cipher_table_s *ct;
- int ct_idx;
- int i;
- const char *name;
- int any = 0;
-
- if( !initialized ) {
- cipher_modules_constructor();
- setup_cipher_table(); /* load static modules on the first call */
- initialized = 1;
- return 1;
- }
+ static int initialized = 0;
- if( done )
- return 0;
- done = 1;
-
- for(ct_idx=0, ct = cipher_table; ct_idx < TABLE_SIZE; ct_idx++,ct++ ) {
- if( !ct->name )
- break;
- }
- if( ct_idx >= TABLE_SIZE-1 )
- BUG(); /* table already full */
- /* now load all extensions */
- while( (name = enum_gnupgext_ciphers( &context, &ct->algo,
- &ct->keylen, &ct->blocksize, &ct->contextsize,
- &ct->setkey, &ct->encrypt, &ct->decrypt)) ) {
- if( ct->blocksize != 8 && ct->blocksize != 16 ) {
- log_info("skipping cipher %d: unsupported blocksize\n", ct->algo);
- continue;
- }
- for(i=0; cipher_table[i].name; i++ )
- if( cipher_table[i].algo == ct->algo )
- break;
- if( cipher_table[i].name ) {
- log_info("skipping cipher %d: already loaded\n", ct->algo );
- continue;
- }
- /* put it into the table */
- if( g10_opt_verbose > 1 )
- log_info("loaded cipher %d (%s)\n", ct->algo, name);
- ct->name = name;
- ct_idx++;
- ct++;
- any = 1;
- /* check whether there are more available table slots */
- if( ct_idx >= TABLE_SIZE-1 ) {
- log_info("cipher table full; ignoring other extensions\n");
- break;
- }
+ if (!initialized )
+ {
+ setup_cipher_table(); /* load static modules on the first call */
+ initialized = 1;
+ return 1;
}
- enum_gnupgext_ciphers( &context, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL );
- return any;
+ return 0;
}
diff --git a/cipher/dynload.c b/cipher/dynload.c
index 09cd1366a..38c6a0c35 100644
--- a/cipher/dynload.c
+++ b/cipher/dynload.c
@@ -1,5 +1,5 @@
/* dynload.c - load cipher extensions
- * Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -23,139 +23,22 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#ifdef HAVE_DL_DLOPEN
- #include <dlfcn.h>
-#elif defined(HAVE_DLD_DLD_LINK)
- #include <dld.h>
-#elif defined(HAVE_DL_SHL_LOAD)
- #include <dl.h>
- #include <errno.h>
-#endif
-#ifdef __MINGW32__
- #include <windows.h>
-#endif
#include "util.h"
#include "cipher.h"
-#include "dynload.h"
-
-#ifdef WITH_SYMBOL_UNDERSCORE
- #define SYMBOL_VERSION "_gnupgext_version"
- #define SYMBOL_ENUM "_gnupgext_enum_func"
-#else
- #define SYMBOL_VERSION "gnupgext_version"
- #define SYMBOL_ENUM "gnupgext_enum_func"
-#endif
-
-
-#ifndef RTLD_NOW
- #define RTLD_NOW 1
-#endif
-
-#ifdef HAVE_DL_SHL_LOAD /* HPUX has shl_load instead of dlopen */
-#define HAVE_DL_DLOPEN
-#define dlopen(PATHNAME,MODE) \
- ((void *) shl_load(PATHNAME, DYNAMIC_PATH | \
- (((MODE) & RTLD_NOW) ? BIND_IMMEDIATE : BIND_DEFERRED), 0L))
-#define dlclose(HANDLE) shl_unload((shl_t) (HANDLE))
-#define dlerror() (errno == 0 ? NULL : strerror(errno))
-
-static void *
-dlsym(void *handle, char *name)
-{
- void *addr;
- if (shl_findsym((shl_t *)&handle,name,(short)TYPE_UNDEFINED,&addr) != 0) {
- return NULL;
- }
- return addr;
-}
-#endif /*HAVE_DL_SHL_LOAD*/
-
-#ifdef __MINGW32__
-#define HAVE_DL_DLOPEN
-#define USE_DYNAMIC_LINKING
-
-static int last_error = 0;
-
-void*
-dlopen(const char *pathname, int mode)
-{
- void *h = LoadLibrary( pathname );
- if (!h) {
- log_error( "LoadLibrary failed ec=%d\n", (int)GetLastError() );
- last_error = 1;
- return NULL;
- }
- return h;
-}
-
-int
-dlclose( void *handle )
-{
- last_error = 0;
- return FreeLibrary( handle );
-}
-
-char*
-dlerror(void)
-{
- static char dlerrstr[10];
- if (last_error) {
- sprintf(dlerrstr, "%d", (int)GetLastError() );
- return dlerrstr;
- }
- return NULL;
-}
-
-void*
-dlsym( void *handle, const char *name )
-{
- void *h = GetProcAddress( handle, name );
- if (!h) {
- log_error( "GetProcAddress failed ec=%d\n", (int)GetLastError() );
- last_error = 1;
- return NULL;
- }
- return h;
-}
-#endif /*__MINGW32__*/
-
-
-
+#include "algorithms.h"
typedef struct ext_list {
struct ext_list *next;
- int internal;
- #ifdef HAVE_DL_DLOPEN
- void *handle; /* handle from dlopen() */
- #else
- int handle; /* if the function has been loaded, this is true */
- #endif
- int failed; /* already tried but failed */
- void * (*enumfunc)(int, int*, int*, int*);
- char *hintstr; /* pointer into name */
char name[1];
} *EXTLIST;
static EXTLIST extensions;
-typedef struct {
- EXTLIST r;
- int seq1;
- int seq2;
- void *sym;
- int reqalgo;
-} ENUMCONTEXT;
-
-
-#ifdef HAVE_DLD_DLD_LINK
-static char *mainpgm_path;
-static int did_dld_init;
-static int dld_available;
-#endif
-
-
-/****************
+/* This is actually not used anymore but we keep a list of already
+ * set extensions modules here.
+ *
+ * Here is the ancient comment:
* Register an extension module. The last registered module will
* be loaded first. A name may have a list of classes
* appended; e.g:
@@ -174,10 +57,6 @@ register_cipher_extension( const char *mainpgm, const char *fname )
EXTLIST r, el, intex;
char *p, *pe;
- #ifdef HAVE_DLD_DLD_LINK
- if( !mainpgm_path && mainpgm && *mainpgm )
- mainpgm_path = m_strdup(mainpgm);
- #endif
if( *fname != DIRSEP_C ) { /* do tilde expansion etc */
char *tmp;
@@ -194,12 +73,8 @@ register_cipher_extension( const char *mainpgm, const char *fname )
strcpy(el->name, fname );
}
/* check whether we have a class hint */
- if( (p=strchr(el->name,'(')) && (pe=strchr(p+1,')')) && !pe[1] ) {
+ if( (p=strchr(el->name,'(')) && (pe=strchr(p+1,')')) && !pe[1] )
*p = *pe = 0;
- el->hintstr = p+1;
- }
- else
- el->hintstr = NULL;
/* check that it is not already registered */
intex = NULL;
@@ -209,473 +84,20 @@ register_cipher_extension( const char *mainpgm, const char *fname )
m_free(el);
return;
}
- else if( r->internal )
- intex = r;
- }
- /* and register */
- /* we put them after the internal extension modules */
- /* this is so that the external modules do not get loaded */
- /* as soon as the internal modules are requested */
- if( intex ) {
- el->next = intex->next;
- intex->next = el;
- }
- else {
- el->next = extensions;
- extensions = el;
- }
-}
-
-void
-register_internal_cipher_extension(
- const char *module_id,
- void * (*enumfunc)(int, int*, int*, int*)
- )
-{
- EXTLIST r, el;
-
- el = m_alloc_clear( sizeof *el + strlen(module_id) );
- strcpy(el->name, module_id );
- el->internal = 1;
-
- /* check that it is not already registered */
- for(r = extensions; r; r = r->next ) {
- if( !compare_filenames(r->name, el->name) ) {
- log_info("extension `%s' already registered\n", el->name );
- m_free(el);
- return;
- }
}
/* and register */
- el->enumfunc = enumfunc;
- #ifdef HAVE_DL_DLOPEN
- el->handle = (void*)1;
- #else
- el->handle = 1;
- #endif
el->next = extensions;
extensions = el;
}
-
-static int
-load_extension( EXTLIST el )
-{
- #ifdef USE_DYNAMIC_LINKING
- char **name;
- #ifdef HAVE_DL_DLOPEN
- const char *err;
- int seq = 0;
- int class, vers;
- void *sym;
- #else
- unsigned long addr;
- int rc;
- #endif
-
- #ifndef __MINGW32__
- /* make sure we are not setuid */
- if( getuid() != geteuid() )
- log_bug("trying to load an extension while still setuid\n");
- #endif
-
- /* now that we are not setuid anymore, we can safely load modules */
- #ifdef HAVE_DL_DLOPEN
- el->handle = dlopen(el->name, RTLD_NOW);
- if( !el->handle ) {
- log_error("%s: error loading extension: %s\n", el->name, dlerror() );
- goto failure;
- }
- name = (char**)dlsym(el->handle, SYMBOL_VERSION);
- if( (err=dlerror()) ) {
- log_error("%s: not a gnupg extension: %s\n", el->name, err );
- goto failure;
- }
- #else /* have dld */
- if( !did_dld_init ) {
- did_dld_init = 1;
- if( !mainpgm_path )
- log_error("DLD is not correctly initialized\n");
- else {
- rc = dld_init( dld_find_executable(mainpgm_path) );
- if( rc )
- log_error("DLD init failed: %s\n", dld_strerror(rc) );
- else
- dld_available = 1;
- }
- }
- if( !dld_available ) {
- log_error("%s: DLD not available\n", el->name );
- goto failure;
- }
-
- rc = dld_link( el->name );
- if( rc ) {
- log_error("%s: error loading extension: %s\n",
- el->name, dld_strerror(rc) );
- goto failure;
- }
- addr = dld_get_symbol(SYMBOL_VERSION);
- if( !addr ) {
- log_error("%s: not a gnupg extension: %s\n",
- el->name, dld_strerror(dld_errno) );
- goto failure;
- }
- name = (char**)addr;
- #endif
-
- if( g10_opt_verbose > 1 )
- log_info("%s: %s%s%s%s\n", el->name, *name,
- el->hintstr? " (":"",
- el->hintstr? el->hintstr:"",
- el->hintstr? ")":"");
-
- #ifdef HAVE_DL_DLOPEN
- sym = dlsym(el->handle, SYMBOL_ENUM);
- if( (err=dlerror()) ) {
- log_error("%s: invalid gnupg extension: %s\n", el->name, err );
- goto failure;
- }
- el->enumfunc = (void *(*)(int,int*,int*,int*))sym;
- #else /* dld */
- addr = dld_get_func(SYMBOL_ENUM);
- if( !addr ) {
- log_error("%s: invalid gnupg extension: %s\n",
- el->name, dld_strerror(dld_errno) );
- goto failure;
- }
- rc = dld_function_executable_p(SYMBOL_ENUM);
- if( rc ) {
- log_error("%s: extension function is not executable: %s\n",
- el->name, dld_strerror(rc) );
- goto failure;
- }
- el->enumfunc = (void *(*)(int,int*,int*,int*))addr;
- el->handle = 1; /* mark as usable */
- #endif
-
- #ifdef HAVE_DL_DLOPEN
- if( g10_opt_verbose > 2 ) {
- /* list the contents of the module */
- while( (sym = (*el->enumfunc)(0, &seq, &class, &vers)) ) {
- if( vers != 1 ) {
- log_info("%s: ignoring func with version %d\n",el->name,vers);
- continue;
- }
- switch( class ) {
- case 11:
- case 21:
- case 31:
- log_info("%s: provides %s algorithm %d\n", el->name,
- class == 11? "md" :
- class == 21? "cipher" : "pubkey",
- *(int*)sym);
- break;
- default:
- /*log_debug("%s: skipping class %d\n", el->name, class);*/
- break;
- }
- }
- }
- #endif
- return 0;
-
- failure:
- #ifdef HAVE_DL_DLOPEN
- if( el->handle ) {
- dlclose(el->handle);
- el->handle = NULL;
- }
- #endif
- el->failed = 1;
- #endif /*USE_DYNAMIC_LINKING*/
- return -1;
-}
-
-#ifdef __riscos__
-typedef
-const char *(*DIGESTS_CAST)(int, size_t*,byte**, int*, int*,
- void (**)(void*),
- void (**)(void*,byte*,size_t),
- void (**)(void*),byte *(**)(void*));
-#endif /* __riscos__ */
-
-int
-enum_gnupgext_digests( void **enum_context,
- int *algo,
- const char *(**r_get_info)( int, size_t*,byte**, int*, int*,
- void (**)(void*),
- void (**)(void*,byte*,size_t),
- void (**)(void*),byte *(**)(void*)) )
-{
- EXTLIST r;
- ENUMCONTEXT *ctx;
-
- if( !*enum_context ) { /* init context */
- ctx = m_alloc_clear( sizeof( *ctx ) );
- ctx->r = extensions;
- ctx->reqalgo = *algo;
- *enum_context = ctx;
- }
- else if( !algo ) { /* release the context */
- m_free(*enum_context);
- *enum_context = NULL;
- return 0;
- }
- else
- ctx = *enum_context;
-
- for( r = ctx->r; r; r = r->next ) {
- int class, vers;
-
- if( r->failed )
- continue;
- if( !r->handle && load_extension(r) )
- continue;
- /* get a digest info function */
- if( ctx->sym )
- goto inner_loop;
- while( (ctx->sym = (*r->enumfunc)(10, &ctx->seq1, &class, &vers)) ) {
- void *sym;
- /* must check class because enumfunc may be wrong coded */
- if( vers != 1 || class != 10 )
- continue;
- inner_loop:
-#ifndef __riscos__
- *r_get_info = ctx->sym;
-#else /* __riscos__ */
- *r_get_info = (DIGESTS_CAST) ctx->sym;
-#endif /* __riscos__ */
- while( (sym = (*r->enumfunc)(11, &ctx->seq2, &class, &vers)) ) {
- if( vers != 1 || class != 11 )
- continue;
- *algo = *(int*)sym;
- ctx->r = r;
- return 1;
- }
- ctx->seq2 = 0;
- }
- ctx->seq1 = 0;
- }
- ctx->r = r;
- return 0;
-}
-
-#ifdef __riscos__
-typedef
-const char *(*CIPHERS_CAST)(int, size_t*, size_t*, size_t*,
- int (**)( void *, byte *, unsigned),
- void (**)( void *, byte *, byte *),
- void (**)( void *, byte *, byte *));
-#endif /* __riscos__ */
-
+/* Return the module name with index SEQ, return NULL as as indication
+ for end of list. */
const char *
-enum_gnupgext_ciphers( void **enum_context, int *algo,
- size_t *keylen, size_t *blocksize, size_t *contextsize,
- int (**setkeyf)( void *c, byte *key, unsigned keylen ),
- void (**encryptf)( void *c, byte *outbuf, byte *inbuf ),
- void (**decryptf)( void *c, byte *outbuf, byte *inbuf )
- )
+dynload_enum_module_names (int seq)
{
- EXTLIST r;
- ENUMCONTEXT *ctx;
- const char * (*finfo)(int, size_t*, size_t*, size_t*,
- int (**)( void *, byte *, unsigned),
- void (**)( void *, byte *, byte *),
- void (**)( void *, byte *, byte *));
+ EXTLIST el = extensions;
- if( !*enum_context ) { /* init context */
- ctx = m_alloc_clear( sizeof( *ctx ) );
- ctx->r = extensions;
- *enum_context = ctx;
- }
- else if( !algo ) { /* release the context */
- m_free(*enum_context);
- *enum_context = NULL;
- return NULL;
- }
- else
- ctx = *enum_context;
-
- for( r = ctx->r; r; r = r->next ) {
- int class, vers;
-
- if( r->failed )
- continue;
- if( !r->handle && load_extension(r) )
- continue;
- /* get a cipher info function */
- if( ctx->sym )
- goto inner_loop;
- while( (ctx->sym = (*r->enumfunc)(20, &ctx->seq1, &class, &vers)) ) {
- void *sym;
- /* must check class because enumfunc may be wrong coded */
- if( vers != 1 || class != 20 )
- continue;
- inner_loop:
-#ifndef __riscos__
- finfo = ctx->sym;
-#else /* __riscos__ */
- finfo = (CIPHERS_CAST) ctx->sym;
-#endif /* __riscos__ */
- while( (sym = (*r->enumfunc)(21, &ctx->seq2, &class, &vers)) ) {
- const char *algname;
- if( vers != 1 || class != 21 )
- continue;
- *algo = *(int*)sym;
- algname = (*finfo)( *algo, keylen, blocksize, contextsize,
- setkeyf, encryptf, decryptf );
- if( algname ) {
- ctx->r = r;
- return algname;
- }
- }
- ctx->seq2 = 0;
- }
- ctx->seq1 = 0;
- }
- ctx->r = r;
- return NULL;
-}
-
-#ifdef __riscos__
-typedef
-const char *(*PUBKEYS_CAST)(int, int *, int *, int *, int *, int *,
- int (**)(int, unsigned, MPI *, MPI **),
- int (**)(int, MPI *),
- int (**)(int, MPI *, MPI , MPI *),
- int (**)(int, MPI *, MPI *, MPI *),
- int (**)(int, MPI *, MPI , MPI *),
- int (**)(int, MPI , MPI *, MPI *,
- int (*)(void*,MPI), void *),
- unsigned (**)( int , MPI *));
-#endif /* __riscos__ */
-
-const char *
-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 (**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 (**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 ),
- unsigned (**get_nbits)( int algo, MPI *pkey ) )
-{
- EXTLIST r;
- ENUMCONTEXT *ctx;
- const char * (*finfo)( int, int *, int *, int *, int *, int *,
- int (**)( int, unsigned, MPI *, MPI **),
- int (**)( int, MPI * ),
- int (**)( int, MPI *, MPI , MPI * ),
- int (**)( int, MPI *, MPI *, MPI * ),
- int (**)( int, MPI *, MPI , MPI * ),
- int (**)( int, MPI , MPI *, MPI *,
- int (*)(void*,MPI), void *),
- unsigned (**)( int , MPI * ) );
-
- if( !*enum_context ) { /* init context */
- ctx = m_alloc_clear( sizeof( *ctx ) );
- ctx->r = extensions;
- *enum_context = ctx;
- }
- else if( !algo ) { /* release the context */
- m_free(*enum_context);
- *enum_context = NULL;
- return NULL;
- }
- else
- ctx = *enum_context;
-
- for( r = ctx->r; r; r = r->next ) {
- int class, vers;
-
- if( r->failed )
- continue;
- if( !r->handle && load_extension(r) )
- continue;
- /* get a pubkey info function */
- if( ctx->sym )
- goto inner_loop;
- while( (ctx->sym = (*r->enumfunc)(30, &ctx->seq1, &class, &vers)) ) {
- void *sym;
- if( vers != 1 || class != 30 )
- continue;
- inner_loop:
-#ifndef __riscos__
- finfo = ctx->sym;
-#else /* __riscos__ */
- finfo = (PUBKEYS_CAST) ctx->sym;
-#endif /* __riscos__ */
- while( (sym = (*r->enumfunc)(31, &ctx->seq2, &class, &vers)) ) {
- const char *algname;
- if( vers != 1 || class != 31 )
- continue;
- *algo = *(int*)sym;
- algname = (*finfo)( *algo, npkey, nskey, nenc, nsig, use,
- generate, check_secret_key, encryptf,
- decryptf, sign, verify, get_nbits );
- if( algname ) {
- ctx->r = r;
- return algname;
- }
- }
- ctx->seq2 = 0;
- }
- ctx->seq1 = 0;
- }
- ctx->r = r;
- return NULL;
-}
-
-
-int (*
-dynload_getfnc_gather_random())(void (*)(const void*, size_t, int), int,
- size_t, int)
-{
- EXTLIST r;
- void *sym;
-
- for( r = extensions; r; r = r->next ) {
- int seq, class, vers;
-
- if( r->failed )
- continue;
- if( !r->handle && load_extension(r) )
- continue;
- seq = 0;
- while( (sym = (*r->enumfunc)(40, &seq, &class, &vers)) ) {
- if( vers != 1 || class != 40 )
- continue;
- return (int (*)(void (*)(const void*, size_t, int), int,
- size_t, int))sym;
- }
- }
- return NULL;
+ for (; el && el->name && seq; el = el->next, seq--)
+ ;
+ return el? el->name:NULL;
}
-
-
-void (*
-dynload_getfnc_fast_random_poll())( void (*)(const void*, size_t, int), int)
-{
- EXTLIST r;
- void *sym;
-
- for( r = extensions; r; r = r->next ) {
- int seq, class, vers;
-
- if( r->failed )
- continue;
- if( !r->handle && load_extension(r) )
- continue;
- seq = 0;
- while( (sym = (*r->enumfunc)(41, &seq, &class, &vers)) ) {
- if( vers != 1 || class != 41 )
- continue;
- return (void (*)( void (*)(const void*, size_t, int), int))sym;
- }
- }
- return NULL;
-}
-
diff --git a/cipher/idea-stub.c b/cipher/idea-stub.c
new file mode 100644
index 000000000..3a9782037
--- /dev/null
+++ b/cipher/idea-stub.c
@@ -0,0 +1,187 @@
+/* idea-stub.c - Dummy module for the deprecated IDEA cipher.
+ * Copyright (C) 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/* IDEA is a patented algorithm and therefore the use of IDEA in
+ countries where this patent is valid can not be allowed due to the
+ terms of the GNU General Public License. Those restrictions are
+ there to help protecting the freedom of software. For more
+ information on the nonsense of software patents and the general
+ problem with this, please see http://www.noepatents.org.
+
+ However for research purposes and in certain situations it might be
+ useful to use this algorithm anyway.
+
+ We provide this stub which will dynload a idea module and is only
+ used if the configure run did't found statically linked file.
+ See http://www.gnupg.org/why-not-dea.html for details.
+*/
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef HAVE_DL_DLOPEN
+ #include <dlfcn.h>
+#endif
+#ifdef __MINGW32__
+ #include <windows.h>
+#endif
+#include "util.h"
+#include "algorithms.h"
+
+#ifndef RTLD_NOW
+ #define RTLD_NOW 1
+#endif
+
+
+#ifdef __MINGW32__
+#define HAVE_DL_DLOPEN
+#define USE_DYNAMIC_LINKING
+
+static int last_error = 0;
+
+void*
+dlopen (const char *pathname, int mode)
+{
+ void *h = LoadLibrary (pathname);
+ if (!h)
+ {
+ log_error ("LoadLibrary failed ec=%d\n", (int)GetLastError());
+ last_error = 1;
+ return NULL;
+ }
+ return h;
+}
+
+int
+dlclose ( void *handle )
+{
+ last_error = 0;
+ return FreeLibrary (handle);
+}
+
+char*
+dlerror (void)
+{
+ static char dlerrstr[10];
+ if (last_error)
+ {
+ sprintf(dlerrstr, "%d", (int)GetLastError() );
+ return dlerrstr;
+ }
+ return NULL;
+}
+
+void*
+dlsym ( void *handle, const char *name )
+{
+ void *h = GetProcAddress (handle, name);
+ if (!h)
+ {
+ log_error ("GetProcAddress failed ec=%d\n", (int)GetLastError());
+ last_error = 1;
+ }
+ return h;
+}
+#endif /*__MINGW32__*/
+
+/* We do only support dlopen and the Windows emulation of it. */
+#ifndef HAVE_DL_DLOPEN
+#undef USE_DYNAMIC_LINKING
+#endif
+
+
+static void *
+load_module (const char *name)
+{
+#ifdef USE_DYNAMIC_LINKING
+ const char *err;
+ void *handle;
+ void *sym;
+
+#ifndef __MINGW32__
+ /* Make sure we are not setuid. */
+ if (getuid() != geteuid())
+ log_bug("trying to load an extension while still setuid\n");
+#endif
+
+ handle = dlopen (name, RTLD_NOW);
+ if (!name)
+ {
+ /*log_error ("error loading module `%s': %s\n", name, dlerror());*/
+ goto failure;
+ }
+
+ sym = dlsym (handle, "idea_get_info");
+ if (dlerror ())
+ sym = dlsym (handle, "_idea_get_info");
+ if ((err=dlerror()))
+ {
+ log_info ("invalid module `%s': %s\n", name, err);
+ goto failure;
+ }
+
+ return sym;
+
+ failure:
+ if (handle)
+ dlclose (handle);
+#endif /*USE_DYNAMIC_LINKING*/
+ return NULL;
+}
+
+
+const char *
+idea_get_info( int algo, size_t *keylen,
+ size_t *blocksize, size_t *contextsize,
+ int (**r_setkey)( void *c, byte *key, unsigned keylen ),
+ void (**r_encrypt)( void *c, byte *outbuf, byte *inbuf ),
+ void (**r_decrypt)( void *c, byte *outbuf, byte *inbuf )
+ )
+{
+ static int initialized;
+ static const char * (*info_fnc)(int, size_t*, size_t*, size_t*,
+ int (**)( void *, byte *, unsigned),
+ void (**)( void *, byte *, byte *),
+ void (**)( void *, byte *, byte *));
+ const char *rstr;
+ int i;
+
+ if (!initialized)
+ {
+ initialized = 1;
+ for (i=0; (rstr = dynload_enum_module_names (i)); i++)
+ {
+ info_fnc = load_module (rstr);
+ if (info_fnc)
+ break;
+ }
+ }
+ if (!info_fnc)
+ return NULL; /* dynloadable module not found. */
+ rstr = info_fnc (algo, keylen, blocksize, contextsize,
+ r_setkey, r_encrypt, r_decrypt);
+ if (rstr && *keylen == 128 && *blocksize == 8
+ && *r_setkey && *r_encrypt && r_decrypt)
+ return rstr;
+ return NULL;
+}
+
diff --git a/cipher/md.c b/cipher/md.c
index 49728638b..85c1f5b2a 100644
--- a/cipher/md.c
+++ b/cipher/md.c
@@ -1,5 +1,5 @@
/* md.c - message digest dispatcher
- * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -27,9 +27,7 @@
#include "util.h"
#include "cipher.h"
#include "errors.h"
-#include "dynload.h"
-#include "rmd.h"
-
+#include "algorithms.h"
/****************
* This structure is used for the list of available algorithms
@@ -54,97 +52,63 @@ static struct md_digest_list_s *digest_list;
static struct md_digest_list_s *
-new_list_item( int algo,
+new_list_item (int algo,
const char *(*get_info)( int, size_t*,byte**, int*, int*,
void (**)(void*),
void (**)(void*,byte*,size_t),
- void (**)(void*),byte *(**)(void*)) )
+ void (**)(void*),byte *(**)(void*)))
{
- struct md_digest_list_s *r;
-
- r = m_alloc_clear( sizeof *r );
- r->algo = algo,
- r->name = (*get_info)( algo, &r->contextsize,
- &r->asnoid, &r->asnlen, &r->mdlen,
- &r->init, &r->write, &r->final, &r->read );
- if( !r->name ) {
- m_free(r);
- r = NULL;
+ struct md_digest_list_s *r;
+
+ r = m_alloc_clear (sizeof *r );
+ r->algo = algo;
+ r->name = (*get_info)( algo, &r->contextsize,
+ &r->asnoid, &r->asnlen, &r->mdlen,
+ &r->init, &r->write, &r->final, &r->read );
+ if (!r->name )
+ {
+ m_free(r);
+ r = NULL;
+ }
+ if (r)
+ {
+ r->next = digest_list;
+ digest_list = r;
}
- return r;
+ return r;
}
-/****************
- * Try to load the modules with the requeste algorithm
- * and return true if new modules are available
- * If req_alog is -1 try to load all digest algorithms.
+/*
+ Load all available hash algorithms and return true. Subsequent
+ calls will return 0.
*/
static int
-load_digest_module( int req_algo )
+load_digest_module (void)
{
- static int initialized = 0;
- static u32 checked_algos[256/32];
- static int checked_all = 0;
- struct md_digest_list_s *r;
- void *context = NULL;
- int algo;
- int any = 0;
- const char *(*get_info)( int, size_t*,byte**, int*, int*,
- void (**)(void*),
- void (**)(void*,byte*,size_t),
- void (**)(void*),byte *(**)(void*));
-
- if( !initialized ) {
- cipher_modules_constructor();
- initialized = 1;
- }
- algo = req_algo;
- if( algo > 255 || !algo )
- return 0; /* algorithm number too high (does not fit into out bitmap)*/
- if( checked_all )
- return 0; /* already called with -1 */
- if( algo < 0 )
- checked_all = 1;
- else if( (checked_algos[algo/32] & (1 << (algo%32))) )
- return 0; /* already checked and not found */
- else
- checked_algos[algo/32] |= (1 << (algo%32));
-
- while( enum_gnupgext_digests( &context, &algo, &get_info ) ) {
- if( req_algo != -1 && algo != req_algo )
- continue;
- for(r=digest_list; r; r = r->next )
- if( r->algo == algo )
- break;
- if( r ) {
- log_info("skipping digest %d: already loaded\n", algo );
- continue;
- }
- r = new_list_item( algo, get_info );
- if( ! r ) {
- log_info("skipping digest %d: no name\n", algo );
- continue;
- }
- /* put it into the list */
- if( g10_opt_verbose > 1 )
- log_info("loaded digest %d\n", algo);
- r->next = digest_list;
- digest_list = r;
- any = 1;
- if( req_algo != -1 )
- break;
- }
- enum_gnupgext_digests( &context, NULL, NULL );
- return any;
-}
+ static int initialized = 0;
+ if (initialized)
+ return 0;
+ initialized = 1;
+
+ /* We load them in reverse order so that the most
+ frequently used are the first in the list. */
+ new_list_item (DIGEST_ALGO_TIGER, tiger_get_info);
+ if (!new_list_item (DIGEST_ALGO_MD5, md5_get_info))
+ BUG ();
+ if (!new_list_item (DIGEST_ALGO_RMD160, rmd160_get_info))
+ BUG ();
+ if (!new_list_item (DIGEST_ALGO_SHA1, sha1_get_info))
+ BUG ();
+
+ return 1;
+}
/****************
- * Map a string to the digest algo
- */
+ * Map a string to the digest algo */
int
string_to_digest_algo( const char *string )
{
@@ -154,7 +118,7 @@ string_to_digest_algo( const char *string )
for(r = digest_list; r; r = r->next )
if( !ascii_strcasecmp( r->name, string ) )
return r->algo;
- } while( !r && load_digest_module(-1) );
+ } while( !r && load_digest_module () );
return 0;
}
@@ -171,7 +135,7 @@ digest_algo_to_string( int algo )
for(r = digest_list; r; r = r->next )
if( r->algo == algo )
return r->name;
- } while( !r && load_digest_module( algo ) );
+ } while( !r && load_digest_module () );
return NULL;
}
@@ -185,7 +149,7 @@ check_digest_algo( int algo )
for(r = digest_list; r; r = r->next )
if( r->algo == algo )
return 0;
- } while( !r && load_digest_module(algo) );
+ } while( !r && load_digest_module () );
return G10ERR_DIGEST_ALGO;
}
@@ -232,7 +196,7 @@ md_enable( MD_HANDLE h, int algo )
for(r = digest_list; r; r = r->next )
if( r->algo == algo )
break;
- } while( !r && load_digest_module( algo ) );
+ } while( !r && load_digest_module () );
if( !r ) {
log_error("md_enable: algorithm %d not available\n", algo );
return;
@@ -457,7 +421,7 @@ md_digest_length( int algo )
if( r->algo == algo )
return r->mdlen;
}
- } while( !r && load_digest_module( algo ) );
+ } while( !r && load_digest_module () );
log_error("WARNING: no length for md algo %d\n", algo);
return 0;
}
@@ -480,7 +444,7 @@ md_asn_oid( int algo, size_t *asnlen, size_t *mdlen )
return r->asnoid;
}
}
- } while( !r && load_digest_module( algo ) );
+ } while( !r && load_digest_module () );
log_bug("no asn for md algo %d\n", algo);
return NULL;
}
@@ -512,13 +476,13 @@ md_stop_debug( MD_HANDLE md )
fclose(md->debug);
md->debug = NULL;
}
- #ifdef HAVE_U64_TYPEDEF
+#ifdef HAVE_U64_TYPEDEF
{ /* a kludge to pull in the __muldi3 for Solaris */
volatile u32 a = (u32)(ulong)md;
volatile u64 b = 42;
volatile u64 c;
c = a * b;
}
- #endif
+#endif
}
diff --git a/cipher/md5.c b/cipher/md5.c
index ef6886eb4..ca605b6fd 100644
--- a/cipher/md5.c
+++ b/cipher/md5.c
@@ -36,7 +36,7 @@
#include <assert.h>
#include "util.h"
#include "memory.h"
-#include "dynload.h"
+#include "algorithms.h"
#include "bithelp.h"
@@ -337,7 +337,7 @@ md5_read( MD5_CONTEXT *hd )
* Returns: A pointer to string describing the algorithm or NULL if
* the ALGO is invalid.
*/
-static const char *
+const char *
md5_get_info( int algo, size_t *contextsize,
byte **r_asnoid, int *r_asnlen, int *r_mdlen,
void (**r_init)( void *c ),
@@ -365,63 +365,3 @@ md5_get_info( int algo, size_t *contextsize,
return "MD5";
}
-
-#ifndef IS_MODULE
-static
-#endif
-const char * const gnupgext_version = "MD5 ($Revision$)";
-
-static struct {
- int class;
- int version;
- int value;
- void (*func)(void);
-} func_table[] = {
- { 10, 1, 0, (void(*)(void))md5_get_info },
- { 11, 1, 1 },
-};
-
-
-#ifndef IS_MODULE
-static
-#endif
-void *
-gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
-{
- void *ret;
- int i = *sequence;
-
- do {
- if( i >= DIM(func_table) || i < 0 )
- return NULL;
- *class = func_table[i].class;
- *vers = func_table[i].version;
- switch( *class ) {
- case 11: case 21: case 31: ret = &func_table[i].value; break;
-#ifndef __riscos__
- default: ret = func_table[i].func; break;
-#else /* __riscos__ */
- default: ret = (void *) func_table[i].func; break;
-#endif /* __riscos__ */
- }
- i++;
- } while( what && what != *class );
-
- *sequence = i;
- return ret;
-}
-
-
-
-
-#ifndef IS_MODULE
-void
-md5_constructor(void)
-{
- register_internal_cipher_extension( gnupgext_version, gnupgext_enum_func );
-}
-#endif
-
-
-
-/* end of file */
diff --git a/cipher/pubkey.c b/cipher/pubkey.c
index 9136fa544..853c518be 100644
--- a/cipher/pubkey.c
+++ b/cipher/pubkey.c
@@ -31,8 +31,6 @@
#include "elgamal.h"
#include "dsa.h"
#include "rsa.h"
-#include "dynload.h"
-
#define TABLE_SIZE 10
@@ -58,6 +56,7 @@ static struct pubkey_table_s pubkey_table[TABLE_SIZE];
static int disabled_algos[TABLE_SIZE];
+#if 0
static int
dummy_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
{ log_bug("no generate() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
@@ -65,6 +64,7 @@ dummy_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
static int
dummy_check_secret_key( int algo, MPI *skey )
{ log_bug("no check_secret_key() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
+#endif
static int
dummy_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
@@ -83,10 +83,11 @@ dummy_verify( int algo, MPI hash, MPI *data, MPI *pkey,
int (*cmp)(void *, MPI), void *opaquev )
{ log_bug("no verify() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
+#if 0
static unsigned
dummy_get_nbits( int algo, MPI *pkey )
{ log_bug("no get_nbits() for %d\n", algo ); return 0; }
-
+#endif
/****************
* Put the static entries into the table.
@@ -215,73 +216,13 @@ static int
load_pubkey_modules(void)
{
static int initialized = 0;
- static int done = 0;
- void *context = NULL;
- struct pubkey_table_s *ct;
- int ct_idx;
- int i;
- const char *name;
- int any = 0;
-
if( !initialized ) {
- cipher_modules_constructor();
setup_pubkey_table();
initialized = 1;
return 1;
}
- if( done )
- return 0;
- done = 1;
- for(ct_idx=0, ct = pubkey_table; ct_idx < TABLE_SIZE; ct_idx++,ct++ ) {
- if( !ct->name )
- break;
- }
- if( ct_idx >= TABLE_SIZE-1 )
- BUG(); /* table already full */
- /* now load all extensions */
- while( (name = enum_gnupgext_pubkeys( &context, &ct->algo,
- &ct->npkey, &ct->nskey, &ct->nenc,
- &ct->nsig, &ct->use,
- &ct->generate,
- &ct->check_secret_key,
- &ct->encrypt,
- &ct->decrypt,
- &ct->sign,
- &ct->verify,
- &ct->get_nbits )) ) {
- for(i=0; pubkey_table[i].name; i++ )
- if( pubkey_table[i].algo == ct->algo )
- break;
- if( pubkey_table[i].name ) {
- log_info("skipping pubkey %d: already loaded\n", ct->algo );
- continue;
- }
-
- if( !ct->generate ) ct->generate = dummy_generate;
- if( !ct->check_secret_key ) ct->check_secret_key =
- dummy_check_secret_key;
- if( !ct->encrypt ) ct->encrypt = dummy_encrypt;
- if( !ct->decrypt ) ct->decrypt = dummy_decrypt;
- if( !ct->sign ) ct->sign = dummy_sign;
- if( !ct->verify ) ct->verify = dummy_verify;
- if( !ct->get_nbits ) ct->get_nbits= dummy_get_nbits;
- /* put it into the table */
- if( g10_opt_verbose > 1 )
- log_info("loaded pubkey %d (%s)\n", ct->algo, name);
- ct->name = name;
- ct_idx++;
- ct++;
- any = 1;
- /* check whether there are more available table slots */
- if( ct_idx >= TABLE_SIZE-1 ) {
- log_info("pubkey table full; ignoring other extensions\n");
- break;
- }
- }
- enum_gnupgext_pubkeys( &context, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL );
- return any;
+ return 0;
}
diff --git a/cipher/rand-internal.h b/cipher/rand-internal.h
index 6f5b52bae..eb81174f8 100644
--- a/cipher/rand-internal.h
+++ b/cipher/rand-internal.h
@@ -20,12 +20,16 @@
#ifndef G10_RAND_INTERNAL_H
#define G10_RAND_INTERNAL_H
-void rndlinux_constructor(void);
-void rndunix_constructor(void);
-void rndw32_constructor(void);
-void rndos2_constructor(void);
-void rndatari_constructor(void);
-void rndmvs_constructor(void);
-void rndriscos_constructor(void);
+int rndunix_gather_random (void (*add)(const void*, size_t, int),
+ int requester, size_t length, int level);
+int rndlinux_gather_random (void (*add)(const void*, size_t, int),
+ int requester, size_t length, int level);
+int rndegd_gather_random (void (*add)(const void*, size_t, int),
+ int requester, size_t length, int level );
+int rndw32_gather_random (void (*add)(const void*, size_t, int),
+ int requester, size_t length, int level);
+int rndw32_gather_random_fast (void (*add)(const void*, size_t, int),
+ int requester );
+
#endif /*G10_RAND_INTERNAL_H*/
diff --git a/cipher/random.c b/cipher/random.c
index 2c958d9d4..1d7bf8a93 100644
--- a/cipher/random.c
+++ b/cipher/random.c
@@ -1,5 +1,5 @@
/* random.c - random number generator
- * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -56,8 +56,7 @@
#include "i18n.h"
#include "random.h"
#include "rand-internal.h"
-#include "dynload.h"
-
+#include "algorithms.h"
#ifndef RAND_MAX /* for SunOS */
#define RAND_MAX 32767
@@ -125,6 +124,37 @@ static struct {
ulong naddbytes;
} rndstats;
+
+static int (*
+getfnc_gather_random (void))(void (*)(const void*, size_t, int), int,
+ size_t, int)
+{
+#ifdef USE_RNDLINUX
+ return rndlinux_gather_random;
+#endif
+#ifdef USE_RNDUNIX
+ return rndunix_gather_random;
+#endif
+#ifdef USE_RNDEGD
+ return rndegd_gather_random;
+#endif
+#ifdef USE_RNDW32
+ return rndw32_gather_random;
+#endif
+ return NULL;
+}
+
+static void (*
+getfnc_fast_random_poll (void))( void (*)(const void*, size_t, int), int)
+{
+#ifdef USE_RNDW32
+ return rndw32_gather_random_fast;
+#endif
+ return NULL;
+}
+
+
+
static void
initialize(void)
{
@@ -136,7 +166,6 @@ initialize(void)
keypool = secure_alloc ? m_alloc_secure_clear(POOLSIZE+BLOCKLEN)
: m_alloc_clear(POOLSIZE+BLOCKLEN);
is_initialized = 1;
- cipher_modules_constructor();
}
static void
@@ -560,7 +589,7 @@ fast_random_poll()
if( !is_initialized )
initialize();
initialized = 1;
- fnc = dynload_getfnc_fast_random_poll();
+ fnc = getfnc_fast_random_poll();
}
if( fnc ) {
(*fnc)( add_randomness, 1 );
@@ -637,7 +666,7 @@ read_random_source( int requester, size_t length, int level )
if( !fnc ) {
if( !is_initialized )
initialize();
- fnc = dynload_getfnc_gather_random();
+ fnc = getfnc_gather_random();
if( !fnc ) {
faked_rng = 1;
fnc = gather_faked;
@@ -685,3 +714,4 @@ gather_faked( void (*add)(const void*, size_t, int), int requester,
return 0; /* okay */
}
+
diff --git a/cipher/rmd160.c b/cipher/rmd160.c
index e35647af6..54dec6a15 100644
--- a/cipher/rmd160.c
+++ b/cipher/rmd160.c
@@ -26,8 +26,8 @@
#include "util.h"
#include "memory.h"
#include "rmd.h"
-#include "cipher.h" /* only used for the rmd160_hash_buffer() prototype */
-#include "dynload.h"
+#include "cipher.h" /* for rmd160_hash_buffer */
+#include "algorithms.h"
#include "bithelp.h"
@@ -558,7 +558,7 @@ rmd160_hash_buffer( char *outbuf, const char *buffer, size_t length )
* Returns: A pointer to string describing the algorithm or NULL if
* the ALGO is invalid.
*/
-static const char *
+const char *
rmd160_get_info( int algo, size_t *contextsize,
byte **r_asnoid, int *r_asnlen, int *r_mdlen,
void (**r_init)( void *c ),
@@ -586,67 +586,3 @@ rmd160_get_info( int algo, size_t *contextsize,
return "RIPEMD160";
}
-
-#ifndef IS_MODULE
-static
-#endif
-const char * const gnupgext_version = "RMD160 ($Revision$)";
-
-static struct {
- int class;
- int version;
- int value;
- void (*func)(void);
-} func_table[] = {
- { 10, 1, 0, (void(*)(void))rmd160_get_info },
- { 11, 1, 3 },
-};
-
-
-#ifndef IS_MODULE
-static
-#endif
-void *
-gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
-{
- void *ret;
- int i = *sequence;
-
- do {
- if( i >= DIM(func_table) || i < 0 ) {
- return NULL;
- }
- *class = func_table[i].class;
- *vers = func_table[i].version;
- switch( *class ) {
- case 11:
- case 21:
- case 31:
- ret = &func_table[i].value;
- break;
- default:
-#ifndef __riscos__
- ret = func_table[i].func;
-#else /* __riscos__ */
- ret = (void *) func_table[i].func;
-#endif /* __riscos__ */
- break;
- }
- i++;
- } while( what && what != *class );
-
- *sequence = i;
- return ret;
-}
-
-
-
-
-#ifndef IS_MODULE
-void
-rmd160_constructor(void)
-{
- register_internal_cipher_extension( gnupgext_version, gnupgext_enum_func );
-}
-#endif
-
diff --git a/cipher/rndegd.c b/cipher/rndegd.c
index 64226eabb..7503ab464 100644
--- a/cipher/rndegd.c
+++ b/cipher/rndegd.c
@@ -1,5 +1,5 @@
/* rndegd.c - interface to the EGD
- * Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+ * Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -19,6 +19,9 @@
*/
#include <config.h>
+
+#ifdef USE_RNDEG
+
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
@@ -33,14 +36,10 @@
#include "types.h"
#include "util.h"
#include "ttyio.h"
-#include "dynload.h"
+#include "algorithms.h"
#include "cipher.h"
+#include "i18n.h"
-#ifdef IS_MODULE
- #define _(a) (a)
-#else
- #include "i18n.h"
-#endif
#ifndef offsetof
#define offsetof(type, member) ((size_t) &((type *)0)->member)
@@ -76,6 +75,11 @@ do_read( int fd, void *buf, size_t nbytes )
} while( n == -1 && errno == EINTR );
if( n == -1 )
return -1;
+ else if( n == 0 ) {
+ /* EGD probably died. */
+ errno = ECONNRESET;
+ return -1;
+ }
nread += n;
} while( nread < nbytes );
return nbytes;
@@ -91,8 +95,8 @@ do_read( int fd, void *buf, size_t nbytes )
* Using a level of 0 should never block and better add nothing
* to the pool. So this is just a dummy for EGD.
*/
-static int
-gather_random( void (*add)(const void*, size_t, int), int requester,
+int
+rndegd_gather_random( void (*add)(const void*, size_t, int), int requester,
size_t length, int level )
{
static int fd = -1;
@@ -175,11 +179,7 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
}
if( length ) {
- #ifdef IS_MODULE
- fprintf( stderr,
- #else
tty_printf(
- #endif
_("Please wait, entropy is being gathered. Do some work if it would\n"
"keep you from getting bored, because it will improve the quality\n"
"of the entropy.\n") );
@@ -205,51 +205,4 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
return 0; /* success */
}
-
-
-#ifndef IS_MODULE
-static
-#endif
-const char * const gnupgext_version = "RNDEGD ($Revision$)";
-
-static struct {
- int class;
- int version;
- int (*func)(void);
-} func_table[] = {
- { 40, 1, (int (*)(void))gather_random },
-};
-
-
-#ifndef IS_MODULE
-static
-#endif
-void *
-gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
-{
- void *ret;
- int i = *sequence;
-
- do {
- if ( i >= DIM(func_table) || i < 0 ) {
- return NULL;
- }
- *class = func_table[i].class;
- *vers = func_table[i].version;
- ret = func_table[i].func;
- i++;
- } while ( what && what != *class );
-
- *sequence = i;
- return ret;
-}
-
-#ifndef IS_MODULE
-void
-rndegd_constructor(void)
-{
- register_internal_cipher_extension( gnupgext_version,
- gnupgext_enum_func );
-}
-#endif
-
+#endif /*USE_RNDEGD*/
diff --git a/cipher/rndlinux.c b/cipher/rndlinux.c
index 0b138fcda..c31b7f71c 100644
--- a/cipher/rndlinux.c
+++ b/cipher/rndlinux.c
@@ -20,6 +20,9 @@
#include <config.h>
+
+#ifdef USE_RNDLINUX
+
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
@@ -41,17 +44,12 @@
#include "types.h"
#include "util.h"
#include "ttyio.h"
-#include "dynload.h"
+#include "algorithms.h"
-#ifdef IS_MODULE
- #define _(a) (a)
-#else
- #include "i18n.h"
-#endif
+#include "i18n.h"
static int open_device( const char *name, int minor );
-static int gather_random( void (*add)(const void*, size_t, int), int requester,
- size_t length, int level );
+
#if 0
#ifdef HAVE_DEV_RANDOM_IOCTL
@@ -92,8 +90,8 @@ open_device( const char *name, int minor )
* Note: Using a level of 0 should never block and better add nothing
* to the pool. This is easy to accomplish with /dev/urandom.
*/
-static int
-gather_random( void (*add)(const void*, size_t, int), int requester,
+int
+rndlinux_gather_random( void (*add)(const void*, size_t, int), int requester,
size_t length, int level )
{
static int fd_urandom = -1;
@@ -132,11 +130,7 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
tv.tv_usec = 0;
if( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) {
if( !warn )
- #ifdef IS_MODULE
- fprintf(stderr,
- #else
tty_printf(
- #endif
_("\n"
"Not enough random bytes available. Please do some other work to give\n"
"the OS a chance to collect more entropy! (Need %d more bytes)\n"), (int)length );
@@ -144,11 +138,7 @@ _("\n"
continue;
}
else if( rc == -1 ) {
- #ifdef IS_MODULE
- fprintf(stderr,
- #else
tty_printf(
- #endif
"select() error: %s\n", strerror(errno));
continue;
}
@@ -171,70 +161,4 @@ _("\n"
return 0; /* success */
}
-
-
-#ifndef IS_MODULE
-static
-#endif
-const char * const gnupgext_version = "RNDLINUX ($Revision$)";
-
-static struct {
- int class;
- int version;
- int (*func)(void);
-} func_table[] = {
- { 40, 1, (int (*)(void))gather_random },
-};
-
-
-
-/****************
- * Enumerate the names of the functions together with informations about
- * this function. Set sequence to an integer with a initial value of 0 and
- * do not change it.
- * If what is 0 all kind of functions are returned.
- * Return values: class := class of function:
- * 10 = message digest algorithm info function
- * 11 = integer with available md algorithms
- * 20 = cipher algorithm info function
- * 21 = integer with available cipher algorithms
- * 30 = public key algorithm info function
- * 31 = integer with available pubkey algorithms
- * 40 = get gather_random function
- * 41 = get fast_random_poll function
- * version = interface version of the function/pointer
- * (currently this is 1 for all functions)
- */
-
-#ifndef IS_MODULE
-static
-#endif
-void *
-gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
-{
- void *ret;
- int i = *sequence;
-
- do {
- if ( i >= DIM(func_table) || i < 0 ) {
- return NULL;
- }
- *class = func_table[i].class;
- *vers = func_table[i].version;
- ret = func_table[i].func;
- i++;
- } while ( what && what != *class );
-
- *sequence = i;
- return ret;
-}
-
-#ifndef IS_MODULE
-void
-rndlinux_constructor(void)
-{
- register_internal_cipher_extension( gnupgext_version,
- gnupgext_enum_func );
-}
-#endif
-
+#endif /*USE_RNDLINUX*/
diff --git a/cipher/rndunix.c b/cipher/rndunix.c
index a46b5ec97..c8d140efe 100644
--- a/cipher/rndunix.c
+++ b/cipher/rndunix.c
@@ -48,6 +48,9 @@
/* General includes */
#include <config.h>
+
+#ifdef USE_RNDUNIX
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -768,9 +771,9 @@ read_a_msg( int fd, GATHER_MSG *msg )
* Using a level of 0 should never block and better add nothing
* to the pool. So this is just a dummy for this gatherer.
*/
-static int
-gather_random( void (*add)(const void*, size_t, int), int requester,
- size_t length, int level )
+int
+rndunix_gather_random( void (*add)(const void*, size_t, int), int requester,
+ size_t length, int level )
{
static pid_t gatherer_pid = 0;
static int pipedes[2];
@@ -846,70 +849,4 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
return 0;
}
-
-
-#ifndef IS_MODULE
-static
-#endif
-const char * const gnupgext_version = "RNDUNIX ($Revision$)";
-
-
-static struct {
- int class;
- int version;
- int (*func)(void);
-} func_table[] = {
- { 40, 1, (int (*)(void))gather_random },
-};
-
-/****************
- * Enumerate the names of the functions together with informations about
- * this function. Set sequence to an integer with a initial value of 0 and
- * do not change it.
- * If what is 0 all kind of functions are returned.
- * Return values: class := class of function:
- * 10 = message digest algorithm info function
- * 11 = integer with available md algorithms
- * 20 = cipher algorithm info function
- * 21 = integer with available cipher algorithms
- * 30 = public key algorithm info function
- * 31 = integer with available pubkey algorithms
- * 40 = get read_random_source() function
- * 41 = get fast_random_poll function
- * version = interface version of the function/pointer
- * (currently this is 1 for all functions)
- */
-
-#ifndef IS_MODULE
-static
-#endif
-void *
-gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
-{
- void *ret;
- int i = *sequence;
-
- do {
- if ( i >= DIM(func_table) || i < 0 ) {
- return NULL;
- }
- *class = func_table[i].class;
- *vers = func_table[i].version;
- ret = func_table[i].func;
- i++;
- } while ( what && what != *class );
-
- *sequence = i;
- return ret;
-}
-
-#ifndef IS_MODULE
-void
-rndunix_constructor(void)
-{
- register_internal_cipher_extension( gnupgext_version,
- gnupgext_enum_func );
-}
-#endif
-
-
+#endif /*USE_RNDUNIX*/
diff --git a/cipher/rndw32.c b/cipher/rndw32.c
index f58d45866..87aa20878 100644
--- a/cipher/rndw32.c
+++ b/cipher/rndw32.c
@@ -1,5 +1,5 @@
/* rndw32.c - W32 entropy gatherer
- * Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+ * Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
* Copyright Peter Gutmann, Matt Thomlinson and Blake Coverett 1996-1999
*
* This file is part of GnuPG.
@@ -60,6 +60,9 @@
*/
#include <config.h>
+
+#ifdef USE_RNDW32
+
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
@@ -74,230 +77,13 @@
#include "types.h"
#include "util.h"
-#include "dynload.h"
-
-/* We do not use the netropy DLL anymore because a standalone program is
- * easier to maintain and */
-/*#define USE_ENTROPY_DLL*/
+#include "algorithms.h"
-
-
-#ifdef IS_MODULE
- #define _(a) (a)
-#else
- #include "i18n.h"
-#endif
+#include "i18n.h"
static int debug_me;
-#ifdef USE_ENTROPY_DLL
-
-#define WIN32_SLOW_SEEDER 0
-#define WIN32_FAST_SEEDER 1
-
-#define PCP_SUCCESS 0
-#define PCP_NULL_POINTER 1
-#define PCP_SEEDER_FAILED 2
-#define PCP_SEEDER_NO_MEM 3
-#define PCP_SEEDER_TOO_SMALL 4
-#define PCP_DLL_LOAD_FAILED 5
-#define PCP_UNKNOWN_PLATFORM 6
-#define PCP_ERROR_VERSION 7
-#define PCP_DLL_FUNC 8
-#define PCP_UNKNOWN_SEEDER_TYPE 9
-
-
-/****************
- * We sometimes get a SEEDER_TOO_SMALL error, in which case we increment
- * the internal buffer by SEEDER_INC_CHUNK until we reach MAX_SEEDER_SIZE
- * MAX_SEEDER_SIZE is used as an arbitrary limit to protect against
- * bugs in Winseed.
- */
-#define MAX_SEEDER_SIZE 500000
-#define SEEDER_INC_CHUNK 50000
-
-
-typedef void *WIN32_SEEDER;
-
-static WIN32_SEEDER (WINAPI *create_instance)( byte type, unsigned int *reason);
-static void (WINAPI *delete_instance)( WIN32_SEEDER that );
-static unsigned int (WINAPI *get_internal_seed_size)( WIN32_SEEDER that );
-static void (WINAPI *set_internal_seed_size)( WIN32_SEEDER that,
- unsigned int new_size);
-static unsigned int (WINAPI *get_expected_seed_size)( WIN32_SEEDER that);
-static unsigned int (WINAPI *get_seed)( WIN32_SEEDER that, byte *buffer,
- unsigned int *desired_length);
-
-static WIN32_SEEDER slow_seeder, fast_seeder;
-static byte *entropy_buffer;
-static size_t entropy_buffer_size;
-
-/****************
- * Load and initialize the winseed DLL
- * NOTE: winseed is not part of the GnuPG distribution. It should be available
- * at the GNU crypto FTP server site.
- * We do not load the DLL on demand to have a better control over the
- * location of the library.
- */
-static void
-load_and_init_winseed( void )
-{
- HANDLE hInstance;
- void *addr;
- unsigned int reason = 0;
- unsigned int n1, n2;
- const char *dllname;
-
- dllname = read_w32_registry_string( "HKEY_LOCAL_MACHINE",
- "Software\\GNU\\GnuPG",
- "EntropyDLL" );
- if( !dllname )
- dllname = "c:/gnupg/entropy.dll";
-
- hInstance = LoadLibrary( dllname );
- if( !hInstance )
- goto failure;
- if( !(addr = GetProcAddress( hInstance, "WS_create_instance" )) )
- goto failure;
- create_instance = addr;
- if( !(addr = GetProcAddress( hInstance, "WS_delete_instance" )) )
- goto failure;
- delete_instance = addr;
- if( !(addr = GetProcAddress( hInstance, "WS_get_internal_seed_size" )) )
- goto failure;
- get_internal_seed_size = addr;
- if( !(addr = GetProcAddress( hInstance, "WS_set_internal_seed_size" )) )
- goto failure;
- set_internal_seed_size = addr;
- if( !(addr = GetProcAddress( hInstance, "WS_get_expected_seed_size" )) )
- goto failure;
- get_expected_seed_size = addr;
- if( !(addr = GetProcAddress( hInstance, "WS_get_seed" )) )
- goto failure;
- get_seed = addr;
-
- /* we have all the functions - init the system */
- slow_seeder = create_instance( WIN32_SLOW_SEEDER, &reason);
- if( !slow_seeder ) {
- g10_log_fatal("error creating winseed slow seeder: rc=%u\n", reason );
- goto failure;
- }
- fast_seeder = create_instance( WIN32_FAST_SEEDER, &reason);
- if( !fast_seeder ) {
- g10_log_fatal("error creating winseed fast seeder: rc=%u\n", reason );
- goto failure;
- }
- n1 = get_internal_seed_size( slow_seeder );
- /*g10_log_info("slow buffer size=%u\n", n1);*/
- n2 = get_internal_seed_size( fast_seeder );
- /*g10_log_info("fast buffer size=%u\n", n2);*/
-
- entropy_buffer_size = n1 > n2? n1: n2;
- entropy_buffer = m_alloc( entropy_buffer_size );
- /*g10_log_info("using a buffer of size=%u\n", entropy_buffer_size );*/
-
- return;
-
- failure:
- g10_log_fatal("error loading winseed DLL `%s'\n", dllname );
-}
-
-
-
-
-
-/* Note: we always use the highest level.
- * TO boost the performance we may want to add some
- * additional code for level 1
- */
-static int
-gather_random( void (*add)(const void*, size_t, int), int requester,
- size_t length, int level )
-{
- unsigned int result;
- unsigned int nbytes;
-
- if( !level )
- return 0;
-
- if( !slow_seeder )
- load_and_init_winseed();
-
- /* Our estimation on how much entropy we should use is very vague.
- * Winseed delivers some amount of entropy on each slow poll and
- * we add it to our random pool. Depending on the required quality
- * level we adjust the requested length so that for higher quality
- * we make sure to add more entropy to our pool. However, as we don't
- * like to waste any entropy collected by winseed, we always add
- * at least everything we got from winseed.
- */
- if( level > 1 )
- length *= 100;
- else if( level > 0 )
- length *= 10;
-
- for(;;) {
- nbytes = entropy_buffer_size;
- result = get_seed( slow_seeder, entropy_buffer, &nbytes);
- if( result == PCP_SEEDER_TOO_SMALL ) {
- unsigned int n1 = get_internal_seed_size( slow_seeder );
-
- if( n1 > MAX_SEEDER_SIZE ) {
- g10_log_fatal("rndw32: internal seeder problem (size=%u)\n",
- n1);
- return -1; /* actually never reached */
- }
- n1 += SEEDER_INC_CHUNK;
- set_internal_seed_size( slow_seeder, n1 );
- if( n1 > entropy_buffer_size ) {
- entropy_buffer_size = n1;
- entropy_buffer = m_realloc( entropy_buffer,
- entropy_buffer_size );
- }
- continue;
- }
-
-
- if( result ) {
- g10_log_fatal("rndw32: get_seed(slow) failed: rc=%u\n", result);
- return -1; /* actually never reached */
- }
- /*g10_log_info("rndw32: slow poll level %d, need %u, got %u\n",
- level, (unsigned int)length, (unsigned int)nbytes );*/
- (*add)( entropy_buffer, nbytes, requester );
- if( length <= nbytes )
- return 0; /* okay */
- length -= nbytes;
- }
-}
-
-static int
-gather_random_fast( void (*add)(const void*, size_t, int), int requester )
-{
- unsigned int result;
- unsigned int nbytes;
-
- if( !fast_seeder )
- load_and_init_winseed();
-
- /* winseed delivers a constant ammount of entropy for a fast
- * poll. We can simply use this and add it to the pool; no need
- * a loop like it is used in the slow poll */
- nbytes = entropy_buffer_size;
- result = get_seed( fast_seeder, entropy_buffer, &nbytes);
- if( result ) {
- g10_log_fatal("rndw32: get_seed(fast) failed: rc=%u\n", result);
- return -1; /* actually never reached */
- }
- /*g10_log_info("rndw32: fast poll got %u\n", (unsigned int)nbytes );*/
- (*add)( entropy_buffer, nbytes, requester );
- return 0;
-}
-
-#else /* !USE_ENTROPY_DLL */
-/* This is the new code which does not require the entropy.dll */
-
/*
* Definitions which are missing from the current GNU Windows32Api
*/
@@ -731,9 +517,9 @@ slow_gatherer_windowsNT( void (*add)(const void*, size_t, int), int requester )
}
-static int
-gather_random( void (*add)(const void*, size_t, int), int requester,
- size_t length, int level )
+int
+rndw32_gather_random (void (*add)(const void*, size_t, int), int requester,
+ size_t length, int level )
{
static int is_initialized;
static int is_windowsNT, has_toolhelp;
@@ -783,8 +569,8 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
-static int
-gather_random_fast( void (*add)(const void*, size_t, int), int requester )
+int
+rndw32_gather_random_fast( void (*add)(const void*, size_t, int), int requester )
{
static int addedFixedItems = 0;
@@ -915,58 +701,4 @@ gather_random_fast( void (*add)(const void*, size_t, int), int requester )
}
-
-
-
-#endif /* !USE_ENTROPY_DLL */
-
-
-#ifndef IS_MODULE
-static
-#endif
-const char * const gnupgext_version = "RNDW32 ($Revision$)";
-
-static struct {
- int class;
- int version;
- void *func;
-} func_table[] = {
- { 40, 1, gather_random },
- { 41, 1, gather_random_fast },
-};
-
-
-#ifndef IS_MODULE
-static
-#endif
-void *
-gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
-{
- void *ret;
- int i = *sequence;
-
- debug_me = !!getenv("DEBUG_RNDW32");
-
- do {
- if ( i >= DIM(func_table) || i < 0 ) {
- return NULL;
- }
- *class = func_table[i].class;
- *vers = func_table[i].version;
- ret = func_table[i].func;
- i++;
- } while ( what && what != *class );
-
- *sequence = i;
- return ret;
-}
-
-#ifndef IS_MODULE
-void
-rndw32_constructor(void)
-{
- register_internal_cipher_extension( gnupgext_version,
- gnupgext_enum_func );
-}
-#endif
-
+#endif /*USE_RNDW32*/
diff --git a/cipher/sha1.c b/cipher/sha1.c
index 77749e4ee..06ca2532b 100644
--- a/cipher/sha1.c
+++ b/cipher/sha1.c
@@ -38,7 +38,7 @@
#include <assert.h>
#include "util.h"
#include "memory.h"
-#include "dynload.h"
+#include "algorithms.h"
#include "bithelp.h"
@@ -331,7 +331,7 @@ sha1_read( SHA1_CONTEXT *hd )
* Returns: A pointer to string describing the algorithm or NULL if
* the ALGO is invalid.
*/
-static const char *
+const char *
sha1_get_info( int algo, size_t *contextsize,
byte **r_asnoid, int *r_asnlen, int *r_mdlen,
void (**r_init)( void *c ),
@@ -357,69 +357,3 @@ sha1_get_info( int algo, size_t *contextsize,
return "SHA1";
}
-
-
-
-#ifndef IS_MODULE
-static
-#endif
-const char * const gnupgext_version = "SHA1 ($Revision$)";
-
-static struct {
- int class;
- int version;
- int value;
- void (*func)(void);
-} func_table[] = {
- { 10, 1, 0, (void(*)(void))sha1_get_info },
- { 11, 1, 2 },
-};
-
-
-#ifndef IS_MODULE
-static
-#endif
-void *
-gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
-{
- void *ret;
- int i = *sequence;
-
- do {
- if( i >= DIM(func_table) || i < 0 ) {
- return NULL;
- }
- *class = func_table[i].class;
- *vers = func_table[i].version;
- switch( *class ) {
- case 11:
- case 21:
- case 31:
- ret = &func_table[i].value;
- break;
- default:
-#ifndef __riscos__
- ret = func_table[i].func;
-#else /* __riscos__ */
- ret = (void *) func_table[i].func;
-#endif /* __riscos__ */
- break;
- }
- i++;
- } while( what && what != *class );
-
- *sequence = i;
- return ret;
-}
-
-
-
-
-#ifndef IS_MODULE
-void
-sha1_constructor(void)
-{
- register_internal_cipher_extension( gnupgext_version, gnupgext_enum_func );
-}
-#endif
-
diff --git a/cipher/tiger.c b/cipher/tiger.c
index 6da715d48..b5e8a8aad 100644
--- a/cipher/tiger.c
+++ b/cipher/tiger.c
@@ -25,7 +25,7 @@
#include <assert.h>
#include "util.h"
#include "memory.h"
-
+#include "algorithms.h"
#ifdef HAVE_U64_TYPEDEF
@@ -879,13 +879,15 @@ tiger_read( TIGER_CONTEXT *hd )
return hd->buf;
}
+#endif /*HAVE_U64_TYPEDEF*/
+
/****************
* Return some information about the algorithm. We need algo here to
* distinguish different flavors of the algorithm.
* Returns: A pointer to string describing the algorithm or NULL if
* the ALGO is invalid.
*/
-static const char *
+const char *
tiger_get_info( int algo, size_t *contextsize,
byte **r_asnoid, int *r_asnlen, int *r_mdlen,
void (**r_init)( void *c ),
@@ -894,6 +896,7 @@ tiger_get_info( int algo, size_t *contextsize,
byte *(**r_read)( void *c )
)
{
+#ifdef HAVE_U64_TYPEDEF
/* 40: SEQUENCE {
* 12: SEQUENCE {
* 8: OCTET STRING :54 49 47 45 52 31 39 32
@@ -904,6 +907,7 @@ tiger_get_info( int algo, size_t *contextsize,
*
* By replacing the 5th byte (0x04) with 0x16 we would have;
* 8: IA5String 'TIGER192'
+ * Fixme: We should use a registered OID.
*/
static byte asn[18] =
{ 0x30, 0x28, 0x30, 0x0c, 0x04, 0x08, 0x54, 0x49, 0x47,
@@ -922,87 +926,7 @@ tiger_get_info( int algo, size_t *contextsize,
*(byte *(**)(TIGER_CONTEXT *))r_read = tiger_read;
return "TIGER192";
-}
-
-
-
-#ifndef IS_MODULE
-static
-#endif
-const char * const gnupgext_version = "TIGER ($Revision$)";
-
-static struct {
- int class;
- int version;
- int value;
- void (*func)(void);
-} func_table[] = {
- { 10, 1, 0, (void(*)(void))tiger_get_info },
- { 11, 1, 6 },
-};
-
-
-
-/****************
- * Enumerate the names of the functions together with informations about
- * this function. Set sequence to an integer with a initial value of 0 and
- * do not change it.
- * If what is 0 all kind of functions are returned.
- * Return values: class := class of function:
- * 10 = message digest algorithm info function
- * 11 = integer with available md algorithms
- * 20 = cipher algorithm info function
- * 21 = integer with available cipher algorithms
- * 30 = public key algorithm info function
- * 31 = integer with available pubkey algorithms
- * version = interface version of the function/pointer
- * (currently this is 1 for all functions)
- */
-#ifndef IS_MODULE
-static
+#else /*!HAVE_U64_TYPEDEF*/
+ return NULL; /* Alorithm not available. */
#endif
-void *
-gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
-{
- void *ret;
- int i = *sequence;
-
- do {
- if( i >= DIM(func_table) || i < 0 ) {
- /*fprintf(stderr, "failed\n");*/
- return NULL;
- }
- *class = func_table[i].class;
- *vers = func_table[i].version;
- switch( *class ) {
- case 11:
- case 21:
- case 31:
- ret = &func_table[i].value;
- break;
- default:
- ret = func_table[i].func;
- break;
- }
- i++;
- } while( what && what != *class );
-
- *sequence = i;
- /*fprintf(stderr, "success\n");*/
- return ret;
-}
-
-
-
-#ifndef IS_MODULE
-void
-tiger_constructor(void)
-{
- register_internal_cipher_extension( gnupgext_version,
- gnupgext_enum_func );
}
-#endif
-
-
-#endif /* HAVE_U64_TYPEDEF */
-