1 /*
2  * Copyright (C) 1998,1999,2000 Nikos Mavroyanopoulos
3  *
4  * This library is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU Library General Public License as published
6  * by the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 
20 /* $Id: mcrypt.c,v 1.19 2002/07/06 10:18:18 nmav Exp $ */
21 
22 /* Changed by Steve Underwood 1999/12/10 to allow an arbitrary number of
23  * streams of encryption. Currently the resulting code is probably not
24  * thread safe, but as far as I could tell the previous code wasn't
25  * either. This version has brute force locking in a lot of places, but
26  * it has not been tested in a multi-threaded manner.
27  * The key locking issue is that the table of encryption streams could
28  * be moved when it is extended. Any address pre-calculated, or in
29  * calculation at the time of the reallocation would be screwed.
30  * This won't happen often, but requires lots of locks - PITA!
31  */
32 
33 /* Changed again at 1999/12/15 to correct the thread safeness. Now it
34  * seems to be thread safe. Brute force locking was removed and
35  * locks per thread were introduced.
36  *						--nikos
37  */
38 
39 /* The above comments are too old! */
40 
41 #ifndef LIBDEFS_H
42 #define LIBDEFS_H
43 #include <libdefs.h>
44 #endif
45 #include <bzero.h>
46 #include <xmemory.h>
47 #include <mcrypt_internal.h>
48 
49 #if 0
50 static int preloaded_symbols = 0;
51 #endif
52 
53 static int internal_end_mcrypt(MCRYPT td);
54 
internal_init_mcrypt(MCRYPT td,const void * key,int lenofkey,const void * IV)55 static int internal_init_mcrypt(MCRYPT td, const void *key, int lenofkey, const void *IV)
56 {
57 	int *sizes = NULL;
58 	int num_of_sizes, i, ok = 0;
59 	int key_size = mcrypt_enc_get_key_size(td);
60 
61 	if (lenofkey > key_size || lenofkey==0) {
62 		return MCRYPT_KEY_LEN_ERROR;	/* error */
63 	}
64 
65 	sizes = mcrypt_enc_get_supported_key_sizes(td, &num_of_sizes);
66 	if (sizes != NULL) {
67 		for (i = 0; i < num_of_sizes; i++) {
68 			if (lenofkey == sizes[i]) {
69 				ok = 1;
70 				break;
71 			}
72 		}
73 	} else {		/* sizes==NULL */
74 		if (num_of_sizes == 0
75 		    && lenofkey <= mcrypt_enc_get_key_size(td))
76 			ok = 1;
77 	}
78 
79 
80 	if (ok == 0) { /* not supported key size */
81 		key_size = mcrypt_enc_get_key_size(td);
82 		if (sizes != NULL) {
83 			for (i = 0; i < num_of_sizes; i++) {
84 				if (lenofkey <= sizes[i]) {
85 					key_size = sizes[i];
86 					break;
87 				}
88 			}
89 		} else { /* well every key size is supported! */
90 			key_size = lenofkey;
91 		}
92 	} else {
93 		key_size = lenofkey;
94 	}
95 	free(sizes);
96 
97 	td->keyword_given = mxcalloc(1, mcrypt_enc_get_key_size(td));
98 	if (td->keyword_given==NULL) return MCRYPT_MEMORY_ALLOCATION_ERROR;
99 
100 	memmove(td->keyword_given, key, lenofkey);
101 	i = mcrypt_get_size(td);
102 	td->akey = mxcalloc(1, i);
103 	if (td->akey==NULL) {
104 		free(td->keyword_given);
105 		return MCRYPT_MEMORY_ALLOCATION_ERROR;
106 	}
107 	i = mcrypt_mode_get_size(td);
108 	if (i > 0) {
109 		td->abuf = mxcalloc(1, i);
110 		if (td->abuf==NULL) {
111 			free(td->keyword_given);
112 			free(td->akey);
113 			return MCRYPT_MEMORY_ALLOCATION_ERROR;
114 		}
115 	}
116 	ok = init_mcrypt(td, td->abuf, key, key_size, IV);
117 	if (ok!=0) {
118 		free(td->keyword_given);
119 		free(td->akey);
120 		free(td->abuf);
121 		return MCRYPT_UNKNOWN_ERROR; /* algorithm error */
122 	}
123 
124 	ok = mcrypt_set_key(td,
125 		       (void *) td->akey,
126 		       (void *) td->keyword_given,
127 		       key_size, IV, IV!=NULL ? mcrypt_enc_get_iv_size(td) : 0);
128 
129 	if (ok!=0) {
130 		internal_end_mcrypt(td);
131 		return MCRYPT_UNKNOWN_ERROR; /* algorithm error */
132 	}
133 
134 	return 0;
135 }
136 
internal_end_mcrypt(MCRYPT td)137 static int internal_end_mcrypt(MCRYPT td)
138 {
139 	mxfree(td->keyword_given, mcrypt_enc_get_key_size(td));
140 	td->keyword_given = NULL;
141 
142 	mxfree(td->akey, mcrypt_get_size(td));
143 	td->akey = NULL;
144 
145 	end_mcrypt(td, td->abuf);
146 	if (td->abuf!=NULL) mxfree(td->abuf, mcrypt_mode_get_size(td));
147 	td->abuf = NULL;
148 
149 	return 0;
150 }
151 
152 /* Generic - High level functions */
153 
154 WIN32DLL_DEFINE
mcrypt_generic_init(const MCRYPT td,const void * key,int lenofkey,const void * IV)155 int mcrypt_generic_init(const MCRYPT td, const void *key, int lenofkey, const void *IV)
156 {
157 	return internal_init_mcrypt(td, key, lenofkey, IV);
158 }
159 
160 WIN32DLL_DEFINE
mcrypt_generic(MCRYPT td,void * plaintext,int len)161 int mcrypt_generic(MCRYPT td, void *plaintext, int len)
162 {
163 	int x;
164 
165 	x = mcrypt(td, td->abuf, plaintext, len);
166 	return x;
167 }
168 
169 WIN32DLL_DEFINE
mdecrypt_generic(MCRYPT td,void * ciphertext,int len)170 int mdecrypt_generic(MCRYPT td, void *ciphertext, int len)
171 {
172 	int x;
173 	x = mdecrypt(td, td->abuf, ciphertext, len);
174 	return x;
175 }
176 
177 WIN32DLL_DEFINE
mcrypt_generic_end(MCRYPT td)178 int mcrypt_generic_end( MCRYPT td)
179 {
180 	if (td==NULL) return MCRYPT_UNKNOWN_ERROR;
181 
182 	if (td->keyword_given!=NULL)
183 		internal_end_mcrypt(td);
184 	mcrypt_module_close(td);
185 	return 0;
186 }
187 
188 WIN32DLL_DEFINE
mcrypt_generic_deinit(MCRYPT td)189 int mcrypt_generic_deinit( MCRYPT td)
190 {
191 	if (td==NULL || td->keyword_given==NULL) return MCRYPT_UNKNOWN_ERROR;
192 
193 	internal_end_mcrypt(td);
194 	return 0;
195 }
196 
197 WIN32DLL_DEFINE
mcrypt_perror(int err)198 void mcrypt_perror(int err)
199 {
200 
201 	switch (err) {
202 	case MCRYPT_UNKNOWN_ERROR:
203 		fprintf(stderr, "Unknown error.\n");
204 		break;
205 	case MCRYPT_ALGORITHM_MODE_INCOMPATIBILITY:
206 		fprintf(stderr,
207 			"Algorithm incompatible with this mode.\n");
208 		break;
209 	case MCRYPT_KEY_LEN_ERROR:
210 		fprintf(stderr, "Key length is not legal.\n");
211 		break;
212 	case MCRYPT_MEMORY_ALLOCATION_ERROR:
213 		fprintf(stderr, "Memory allocation failed.\n");
214 		break;
215 	case MCRYPT_UNKNOWN_MODE:
216 		fprintf(stderr, "Unknown mode.\n");
217 		break;
218 	case MCRYPT_UNKNOWN_ALGORITHM:
219 		fprintf(stderr, "Unknown algorithm.\n");
220 		break;
221 
222 	}
223 	return;
224 }
225 
226 WIN32DLL_DEFINE
mcrypt_strerror(int err)227 const char* mcrypt_strerror(int err)
228 {
229 
230 	switch (err) {
231 	case MCRYPT_UNKNOWN_ERROR:
232 		return "Unknown error.\n";
233 		break;
234 	case MCRYPT_ALGORITHM_MODE_INCOMPATIBILITY:
235 		return	"Algorithm incompatible with this mode.\n";
236 		break;
237 	case MCRYPT_KEY_LEN_ERROR:
238 		return "Key length is not legal.\n";
239 		break;
240 	case MCRYPT_MEMORY_ALLOCATION_ERROR:
241 		return "Memory allocation failed.\n";
242 		break;
243 	case MCRYPT_UNKNOWN_MODE:
244 		return "Unknown mode.\n";
245 		break;
246 	case MCRYPT_UNKNOWN_ALGORITHM:
247 		return "Unknown algorithm.\n";
248 		break;
249 
250 	}
251 	return NULL;
252 }
253 
254 WIN32DLL_DEFINE
mcrypt_free(void * ptr)255 void mcrypt_free(void *ptr)
256 {
257 	free(ptr);
258 }
259