* cipher.c (setup_cipher_table): #ifdef IDEA.
[gnupg.git] / cipher / idea-stub.c
1 /* idea-stub.c - Dummy module for the deprecated IDEA cipher.
2  *      Copyright (C) 2002 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 __MINGW32__
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
55 #ifdef __MINGW32__
56 #define HAVE_DL_DLOPEN
57 #define USE_DYNAMIC_LINKING
58
59 static int last_error = 0;
60     
61 void*
62 dlopen (const char *pathname, int mode)
63 {
64   void *h = LoadLibrary (pathname);
65   if (!h) 
66     {
67       log_error ("LoadLibrary failed ec=%d\n", (int)GetLastError());
68       last_error = 1;
69       return NULL;
70     }
71   return h;
72 }
73
74 int
75 dlclose ( void *handle )
76 {
77   last_error = 0;
78   return FreeLibrary (handle);
79 }
80
81 char*
82 dlerror (void)
83 {
84   static char dlerrstr[10];
85   if (last_error)
86     {
87       sprintf(dlerrstr, "%d", (int)GetLastError() );
88       return dlerrstr;
89     }
90   return NULL;
91 }
92
93 void*
94 dlsym ( void *handle, const char *name )
95 {
96   void *h = GetProcAddress (handle, name);
97   if (!h)
98     {
99       log_error ("GetProcAddress failed ec=%d\n", (int)GetLastError());
100       last_error = 1;
101     }
102   return h;
103 }
104 #endif /*__MINGW32__*/
105
106 /* We do only support dlopen and the Windows emulation of it. */
107 #ifndef HAVE_DL_DLOPEN
108 #undef USE_DYNAMIC_LINKING
109 #endif
110
111
112 static void *
113 load_module (const char *name)
114 {
115 #ifdef USE_DYNAMIC_LINKING
116   const char *err;
117   void *handle;
118   void *sym;
119
120 #ifndef __MINGW32__
121   /* Make sure we are not setuid. */
122   if (getuid() != geteuid())
123     log_bug("trying to load an extension while still setuid\n");
124 #endif
125
126   handle = dlopen (name, RTLD_NOW);
127   if (!handle)
128     {
129       err=dlerror();
130       goto failure;
131     }
132
133   sym = dlsym (handle, "idea_get_info");
134   if (dlerror ())
135     sym = dlsym (handle, "_idea_get_info");
136   if ((err=dlerror())) 
137     goto failure;
138
139   return sym;
140   
141  failure:
142   log_info ("invalid module `%s': %s\n", name?name:"???", err?err:"???");
143   if (handle)
144       dlclose (handle);
145 #endif /*USE_DYNAMIC_LINKING*/
146   return NULL;
147 }
148
149 #ifdef __riscos__
150 typedef
151 const char *(*INFO_CAST)(int, size_t*, size_t*, size_t*,
152                          int  (**)( void *, byte *, unsigned),
153                          void (**)( void *, byte *, byte *),
154                          void (**)( void *, byte *, byte *));
155 #endif /* __riscos__ */
156
157 const char *
158 idea_get_info( int algo, size_t *keylen,
159                    size_t *blocksize, size_t *contextsize,
160                    int  (**r_setkey)( void *c, byte *key, unsigned keylen ),
161                    void (**r_encrypt)( void *c, byte *outbuf, byte *inbuf ),
162                    void (**r_decrypt)( void *c, byte *outbuf, byte *inbuf )
163                  )
164 {
165   static int initialized;
166   static const char * (*info_fnc)(int, size_t*, size_t*, size_t*,
167                                   int  (**)( void *, byte *, unsigned),
168                                   void (**)( void *, byte *, byte *),
169                                   void (**)( void *, byte *, byte *));
170   const char *rstr;
171   int i;
172
173   if (!initialized)
174     {
175       initialized = 1;
176       for (i=0; (rstr = dynload_enum_module_names (i)); i++)
177         {
178 #ifndef __riscos__
179           info_fnc = load_module (rstr);
180 #else /* __riscos__ */
181           info_fnc = (INFO_CAST) load_module (rstr);
182 #endif /* __riscos__ */
183           if (info_fnc)
184             break;
185         }
186     }
187   if (!info_fnc)
188     return NULL; /* dynloadable module not found. */
189   rstr = info_fnc (algo, keylen, blocksize, contextsize,
190                    r_setkey, r_encrypt, r_decrypt);
191   if (rstr && *keylen == 128 && *blocksize == 8
192       && *r_setkey && *r_encrypt && r_decrypt)
193     return rstr;
194   return NULL;
195 }
196