Add gc-rijndael and gc-rijndael-tests modules.
[gnulib.git] / lib / gc-gnulib.c
1 /* gc-gl-common.c --- Common gnulib internal crypto interface functions
2  * Copyright (C) 2002, 2003, 2004, 2005  Simon Josefsson
3  *
4  * This file is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published
6  * by the Free Software Foundation; either version 2, or (at your
7  * option) any later version.
8  *
9  * This file is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this file; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  */
20
21 /* Note: This file is only built if GC uses internal functions. */
22
23 #ifdef HAVE_CONFIG_H
24 # include <config.h>
25 #endif
26
27 /* Get prototype. */
28 #include <gc.h>
29
30 #include <stdlib.h>
31 #include <string.h>
32
33 /* For randomize. */
34 #include <unistd.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <fcntl.h>
38 #include <errno.h>
39
40 #ifdef GC_USE_MD4
41 # include "md4.h"
42 #endif
43 #ifdef GC_USE_MD5
44 # include "md5.h"
45 #endif
46 #ifdef GC_USE_SHA1
47 # include "sha1.h"
48 #endif
49 #ifdef GC_USE_HMAC_MD5
50 # include "hmac.h"
51 #endif
52 #ifdef GC_USE_RIJNDAEL
53 # include "rijndael-api-fst.h"
54 #endif
55
56 Gc_rc
57 gc_init (void)
58 {
59   return GC_OK;
60 }
61
62 void
63 gc_done (void)
64 {
65   return;
66 }
67
68 /* Randomness. */
69
70 static Gc_rc
71 randomize (int level, char *data, size_t datalen)
72 {
73   int fd;
74   const char *device;
75   size_t len = 0;
76   int rc;
77
78   switch (level)
79     {
80     case 0:
81       device = NAME_OF_NONCE_DEVICE;
82       break;
83
84     case 1:
85       device = NAME_OF_PSEUDO_RANDOM_DEVICE;
86       break;
87
88     default:
89       device = NAME_OF_RANDOM_DEVICE;
90       break;
91     }
92
93   fd = open (device, O_RDONLY);
94   if (fd < 0)
95     return GC_RANDOM_ERROR;
96
97   do
98     {
99       ssize_t tmp;
100
101       tmp = read (fd, data, datalen);
102
103       if (tmp < 0)
104         {
105           int save_errno = errno;
106           close (fd);
107           errno = save_errno;
108           return GC_RANDOM_ERROR;
109         }
110
111       len += tmp;
112     }
113   while (len < datalen);
114
115   rc = close (fd);
116   if (rc < 0)
117     return GC_RANDOM_ERROR;
118
119   return GC_OK;
120 }
121
122 Gc_rc
123 gc_nonce (char *data, size_t datalen)
124 {
125   return randomize (0, data, datalen);
126 }
127
128 Gc_rc
129 gc_pseudo_random (char *data, size_t datalen)
130 {
131   return randomize (1, data, datalen);
132 }
133
134 Gc_rc
135 gc_random (char *data, size_t datalen)
136 {
137   return randomize (2, data, datalen);
138 }
139
140 /* Memory allocation. */
141
142 void
143 gc_set_allocators (gc_malloc_t func_malloc,
144                    gc_malloc_t secure_malloc,
145                    gc_secure_check_t secure_check,
146                    gc_realloc_t func_realloc, gc_free_t func_free)
147 {
148   return;
149 }
150 /* Ciphers. */
151
152 typedef struct _gc_cipher_ctx {
153   Gc_cipher alg;
154   Gc_cipher_mode mode;
155 #ifdef GC_USE_RIJNDAEL
156   rijndaelKeyInstance aesEncKey;
157   rijndaelKeyInstance aesDecKey;
158   rijndaelCipherInstance aesContext;
159 #endif
160 } _gc_cipher_ctx;
161
162 Gc_rc
163 gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode,
164                 gc_cipher_handle * outhandle)
165 {
166   _gc_cipher_ctx *ctx;
167   Gc_rc rc = GC_OK;
168
169   ctx = calloc (sizeof (*ctx), 1);
170
171   ctx->alg = alg;
172   ctx->mode = mode;
173
174   switch (alg)
175     {
176 #ifdef GC_USE_RIJNDAEL
177     case GC_AES128:
178     case GC_AES192:
179     case GC_AES256:
180       switch (mode)
181         {
182         case GC_ECB:
183         case GC_CBC:
184           break;
185
186         default:
187           rc = GC_INVALID_CIPHER;
188         }
189       break;
190 #endif
191
192     default:
193       rc = GC_INVALID_CIPHER;
194     }
195
196   if (rc == GC_OK)
197     *outhandle = ctx;
198   else
199     free (ctx);
200
201   return rc;
202 }
203
204 Gc_rc
205 gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key)
206 {
207   _gc_cipher_ctx *ctx = handle;
208
209   switch (ctx->alg)
210     {
211 #ifdef GC_USE_RIJNDAEL
212     case GC_AES128:
213     case GC_AES192:
214     case GC_AES256:
215       {
216         rijndael_rc rc;
217         size_t i;
218         char keyMaterial[RIJNDAEL_MAX_KEY_SIZE + 1];
219
220         for (i = 0; i < keylen; i++)
221           sprintf (&keyMaterial[2*i], "%02x", key[i] & 0xFF);
222
223         rc = rijndaelMakeKey (&ctx->aesEncKey, RIJNDAEL_DIR_ENCRYPT,
224                               keylen * 8, keyMaterial);
225         if (rc < 0)
226           return GC_INVALID_CIPHER;
227
228         rc = rijndaelMakeKey (&ctx->aesDecKey, RIJNDAEL_DIR_DECRYPT,
229                               keylen * 8, keyMaterial);
230         if (rc < 0)
231           return GC_INVALID_CIPHER;
232
233         rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_ECB, NULL);
234         if (rc < 0)
235           return GC_INVALID_CIPHER;
236       }
237       break;
238 #endif
239
240     default:
241       return GC_INVALID_CIPHER;
242     }
243
244   return GC_OK;
245 }
246
247 Gc_rc
248 gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv)
249 {
250   _gc_cipher_ctx *ctx = handle;
251
252   switch (ctx->alg)
253     {
254 #ifdef GC_USE_RIJNDAEL
255     case GC_AES128:
256     case GC_AES192:
257     case GC_AES256:
258       switch (ctx->mode)
259         {
260         case GC_ECB:
261           /* Doesn't use IV. */
262           break;
263
264         case GC_CBC:
265           {
266             rijndael_rc rc;
267             size_t i;
268             char ivMaterial[2 * RIJNDAEL_MAX_IV_SIZE + 1];
269
270             for (i = 0; i < ivlen; i++)
271               sprintf (&ivMaterial[2*i], "%02x", iv[i] & 0xFF);
272
273             rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_CBC,
274                                      ivMaterial);
275             if (rc < 0)
276               return GC_INVALID_CIPHER;
277           }
278           break;
279
280         default:
281           return GC_INVALID_CIPHER;
282         }
283       break;
284 #endif
285
286     default:
287       return GC_INVALID_CIPHER;
288     }
289
290   return GC_OK;
291 }
292
293 Gc_rc
294 gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data)
295 {
296   _gc_cipher_ctx *ctx = handle;
297
298   switch (ctx->alg)
299     {
300 #ifdef GC_USE_RIJNDAEL
301     case GC_AES128:
302     case GC_AES192:
303     case GC_AES256:
304       {
305         int nblocks;
306
307         nblocks = rijndaelBlockEncrypt (&ctx->aesContext, &ctx->aesEncKey,
308                                         data, 8 * len, data);
309         if (nblocks < 0)
310           return GC_INVALID_CIPHER;
311       }
312       break;
313 #endif
314
315     default:
316       return GC_INVALID_CIPHER;
317     }
318
319   return GC_OK;
320 }
321
322 Gc_rc
323 gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data)
324 {
325   _gc_cipher_ctx *ctx = handle;
326
327   switch (ctx->alg)
328     {
329 #ifdef GC_USE_RIJNDAEL
330     case GC_AES128:
331     case GC_AES192:
332     case GC_AES256:
333       {
334         int nblocks;
335
336         nblocks = rijndaelBlockDecrypt (&ctx->aesContext, &ctx->aesDecKey,
337                                         data, 8 * len, data);
338         if (nblocks < 0)
339           return GC_INVALID_CIPHER;
340       }
341       break;
342 #endif
343
344     default:
345       return GC_INVALID_CIPHER;
346     }
347
348   return GC_OK;
349 }
350
351 Gc_rc
352 gc_cipher_close (gc_cipher_handle handle)
353 {
354   _gc_cipher_ctx *ctx = handle;
355
356   if (ctx)
357     free (ctx);
358
359   return GC_OK;
360 }
361
362 /* Hashes. */
363
364 Gc_rc
365 gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf)
366 {
367   switch (hash)
368     {
369 #ifdef GC_USE_MD4
370     case GC_MD4:
371       md4_buffer (in, inlen, resbuf);
372       break;
373 #endif
374
375 #ifdef GC_USE_MD5
376     case GC_MD5:
377       md5_buffer (in, inlen, resbuf);
378       break;
379 #endif
380
381 #ifdef GC_USE_SHA1
382     case GC_SHA1:
383       sha1_buffer (in, inlen, resbuf);
384       break;
385 #endif
386
387     default:
388       return GC_INVALID_HASH;
389     }
390
391   return GC_OK;
392 }
393
394 #ifdef GC_USE_MD4
395 Gc_rc
396 gc_md4 (const void *in, size_t inlen, void *resbuf)
397 {
398   md4_buffer (in, inlen, resbuf);
399   return GC_OK;
400 }
401 #endif
402
403 #ifdef GC_USE_MD5
404 Gc_rc
405 gc_md5 (const void *in, size_t inlen, void *resbuf)
406 {
407   md5_buffer (in, inlen, resbuf);
408   return GC_OK;
409 }
410 #endif
411
412 #ifdef GC_USE_SHA1
413 Gc_rc
414 gc_sha1 (const void *in, size_t inlen, void *resbuf)
415 {
416   sha1_buffer (in, inlen, resbuf);
417   return GC_OK;
418 }
419 #endif
420
421 #ifdef GC_USE_HMAC_MD5
422 Gc_rc
423 gc_hmac_md5 (const void *key, size_t keylen,
424              const void *in, size_t inlen, char *resbuf)
425 {
426   hmac_md5 (key, keylen, in, inlen, resbuf);
427   return GC_OK;
428 }
429 #endif
430
431 #ifdef GC_USE_HMAC_SHA1
432 Gc_rc
433 gc_hmac_sha1 (const void *key, size_t keylen,
434               const void *in, size_t inlen, char *resbuf)
435 {
436   hmac_sha1 (key, keylen, in, inlen, resbuf);
437   return GC_OK;
438 }
439 #endif