* idea-stub.c (load_module, idea_get_info): Return the proper type for
[gnupg.git] / cipher / idea-stub.c
1 /* idea-stub.c - Dummy module for the deprecated IDEA cipher.
2  * Copyright (C) 2002, 2003 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 /* IDEA is a patented algorithm and therefore the use of IDEA in
22    countries where this patent is valid can not be allowed due to the
23    terms of the GNU General Public License.  Those restrictions are
24    there to help protecting the freedom of software.  For more
25    information on the nonsense of software patents and the general
26    problem with this, please see http://www.noepatents.org.
27
28    However for research purposes and in certain situations it might be
29    useful to use this algorithm anyway.  
30
31    We provide this stub which will dynload a idea module and is only 
32    used if the configure run did't found statically linked file.
33    See http://www.gnupg.org/why-not-dea.html for details.
34 */
35
36 #include <config.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41 #ifdef HAVE_DL_DLOPEN
42 #include <dlfcn.h>
43 #endif
44 #ifdef _WIN32
45 #include <windows.h>
46 #endif
47 #include "util.h"
48 #include "algorithms.h"
49
50 #ifndef RTLD_NOW
51 #define RTLD_NOW  1
52 #endif
53
54 #ifdef _WIN32
55 #define HAVE_DL_DLOPEN
56 #define USE_DYNAMIC_LINKING
57
58 static int last_error = 0;
59     
60 void*
61 dlopen (const char *pathname, int mode)
62 {
63   void *h = LoadLibrary (pathname);
64   if (!h) 
65     {
66       log_error ("LoadLibrary failed ec=%d\n", (int)GetLastError());
67       last_error = 1;
68       return NULL;
69     }
70   return h;
71 }
72
73 int
74 dlclose ( void *handle )
75 {
76   last_error = 0;
77   return FreeLibrary (handle);
78 }
79
80 char*
81 dlerror (void)
82 {
83   static char dlerrstr[10];
84   if (last_error)
85     {
86       sprintf(dlerrstr, "%d", (int)GetLastError() );
87       return dlerrstr;
88     }
89   return NULL;
90 }
91
92 void*
93 dlsym ( void *handle, const char *name )
94 {
95   void *h = GetProcAddress (handle, name);
96   if (!h)
97     {
98       log_error ("GetProcAddress failed ec=%d\n", (int)GetLastError());
99       last_error = 1;
100     }
101   return h;
102 }
103 #endif /*_WIN32*/
104
105 /* We do only support dlopen and the Windows emulation of it. */
106 #ifndef HAVE_DL_DLOPEN
107 #undef USE_DYNAMIC_LINKING
108 #endif
109
110 typedef
111 const char *(*INFO_FNC)(int, size_t*, size_t*, size_t*,
112                         int  (**)( void *, byte *, unsigned),
113                         void (**)( void *, byte *, byte *),
114                         void (**)( void *, byte *, byte *));
115
116 static INFO_FNC
117 load_module (const char *name)
118 {
119 #ifdef USE_DYNAMIC_LINKING
120   const char *err;
121   void *handle;
122   void *sym;
123
124 #ifndef _WIN32
125   /* Make sure we are not setuid. */
126   if (getuid() != geteuid())
127     log_bug("trying to load an extension while still setuid\n");
128 #endif
129
130   handle = dlopen (name, RTLD_NOW);
131   if (!handle)
132     {
133       err=dlerror();
134       goto failure;
135     }
136
137   sym = dlsym (handle, "idea_get_info");
138   if (dlerror ())
139     sym = dlsym (handle, "_idea_get_info");
140   if ((err=dlerror())) 
141     goto failure;
142
143   return sym;
144   
145  failure:
146   log_info ("invalid module `%s': %s\n", name?name:"???", err?err:"???");
147   if (handle)
148       dlclose (handle);
149 #endif /*USE_DYNAMIC_LINKING*/
150   return NULL;
151 }
152
153 const char *
154 idea_get_info( int algo, size_t *keylen,
155                    size_t *blocksize, size_t *contextsize,
156                    int  (**r_setkey)( void *c, byte *key, unsigned keylen ),
157                    void (**r_encrypt)( void *c, byte *outbuf, byte *inbuf ),
158                    void (**r_decrypt)( void *c, byte *outbuf, byte *inbuf )
159                  )
160 {
161   static int initialized;
162   static INFO_FNC info_fnc;
163   const char *rstr;
164   int i;
165
166   if (!initialized)
167     {
168       initialized = 1;
169       for (i=0; (rstr = dynload_enum_module_names (i)); i++)
170         {
171           info_fnc = load_module (rstr);
172           if (info_fnc)
173             break;
174         }
175     }
176   if (!info_fnc)
177     return NULL; /* dynloadable module not found. */
178   rstr = info_fnc (algo, keylen, blocksize, contextsize,
179                    r_setkey, r_encrypt, r_decrypt);
180   if (rstr && *keylen == 128 && *blocksize == 8
181       && *r_setkey && *r_encrypt && r_decrypt)
182     return rstr;
183   return NULL;
184 }