Switched to GPLv3.
[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 3 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, see <http://www.gnu.org/licenses/>.
18  */
19
20 /* IDEA is a patented algorithm and therefore the use of IDEA in
21    countries where this patent is valid can not be allowed due to the
22    terms of the GNU General Public License.  Those restrictions are
23    there to help protecting the freedom of software.  For more
24    information on the nonsense of software patents and the general
25    problem with this, please see http://www.noepatents.org.
26
27    However for research purposes and in certain situations it might be
28    useful to use this algorithm anyway.  
29
30    We provide this stub which will dynload a idea module and is only 
31    used if the configure run did't found statically linked file.
32    See http://www.gnupg.org/why-not-dea.html for details.
33 */
34
35 #include <config.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <unistd.h>
40 #ifdef HAVE_DL_DLOPEN
41 #include <dlfcn.h>
42 #endif
43 #ifdef _WIN32
44 #include <windows.h>
45 #endif
46 #include "util.h"
47 #include "algorithms.h"
48
49 #ifndef RTLD_NOW
50 #define RTLD_NOW  1
51 #endif
52
53 #ifdef _WIN32
54 #define HAVE_DL_DLOPEN 1
55 #define USE_DYNAMIC_LINKING 1
56
57 static int last_error = 0;
58     
59 void*
60 dlopen (const char *pathname, int mode)
61 {
62   void *h = LoadLibrary (pathname);
63   if (!h) 
64     {
65       log_error ("LoadLibrary failed: %s\n", w32_strerror (errno));
66       last_error = 1;
67       return NULL;
68     }
69   return h;
70 }
71
72 int
73 dlclose ( void *handle )
74 {
75   last_error = 0;
76   return FreeLibrary (handle);
77 }
78
79
80 const char*
81 dlerror (void)
82 {
83   if (last_error)
84     return w32_strerror (0);
85   return NULL;
86 }
87
88 void*
89 dlsym (void *handle, const char *name)
90 {
91   void *h = GetProcAddress (handle, name);
92   if (!h)
93     {
94       log_error ("GetProcAddress failed: %s\n", w32_strerror (errno));
95       last_error = 1;
96     }
97   return h;
98 }
99 #endif /*_WIN32*/
100
101 /* We do only support dlopen and the Windows emulation of it. */
102 #ifndef HAVE_DL_DLOPEN
103 #undef USE_DYNAMIC_LINKING
104 #endif
105
106 typedef
107 const char *(*INFO_FNC)(int, size_t*, size_t*, size_t*,
108                         int  (**)( void *, const byte *, unsigned),
109                         void (**)( void *, byte *, const byte *),
110                         void (**)( void *, byte *, const byte *));
111
112 static INFO_FNC
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 _WIN32
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 (INFO_FNC)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 const char *
150 idea_get_info( int algo, size_t *keylen,
151                size_t *blocksize, size_t *contextsize,
152                int (**r_setkey)( void *c, const byte *key, unsigned keylen ),
153                void (**r_encrypt)( void *c, byte *outbuf, const byte *inbuf ),
154                void (**r_decrypt)( void *c, byte *outbuf, const byte *inbuf )
155                )
156 {
157   static int initialized;
158   static INFO_FNC info_fnc;
159   const char *rstr;
160   int i;
161
162   if (!initialized)
163     {
164       initialized = 1;
165       for (i=0; (rstr = dynload_enum_module_names (i)); i++)
166         {
167           info_fnc = load_module (rstr);
168           if (info_fnc)
169             break;
170         }
171     }
172   if (!info_fnc)
173     return NULL; /* dynloadable module not found. */
174   rstr = info_fnc (algo, keylen, blocksize, contextsize,
175                    r_setkey, r_encrypt, r_decrypt);
176   if (rstr && *keylen == 128 && *blocksize == 8
177       && *r_setkey && *r_encrypt && r_decrypt)
178     return rstr;
179   return NULL;
180 }