6eff3e3fee4363f488d28b43f34d0e314a3227ba
[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 /* Hashes. */
41 #ifdef GC_USE_MD4
42 # include "md4.h"
43 #endif
44 #ifdef GC_USE_MD5
45 # include "md5.h"
46 #endif
47 #ifdef GC_USE_SHA1
48 # include "sha1.h"
49 #endif
50 #ifdef GC_USE_HMAC_MD5
51 # include "hmac.h"
52 #endif
53
54 /* Ciphers. */
55 #ifdef GC_USE_ARCFOUR
56 # include "arcfour.h"
57 #endif
58 #ifdef GC_USE_ARCTWO
59 # include "arctwo.h"
60 #endif
61 #ifdef GC_USE_DES
62 # include "des.h"
63 #endif
64 #ifdef GC_USE_RIJNDAEL
65 # include "rijndael-api-fst.h"
66 #endif
67
68 Gc_rc
69 gc_init (void)
70 {
71   return GC_OK;
72 }
73
74 void
75 gc_done (void)
76 {
77   return;
78 }
79
80 /* Randomness. */
81
82 static Gc_rc
83 randomize (int level, char *data, size_t datalen)
84 {
85   int fd;
86   const char *device;
87   size_t len = 0;
88   int rc;
89
90   switch (level)
91     {
92     case 0:
93       device = NAME_OF_NONCE_DEVICE;
94       break;
95
96     case 1:
97       device = NAME_OF_PSEUDO_RANDOM_DEVICE;
98       break;
99
100     default:
101       device = NAME_OF_RANDOM_DEVICE;
102       break;
103     }
104
105   fd = open (device, O_RDONLY);
106   if (fd < 0)
107     return GC_RANDOM_ERROR;
108
109   do
110     {
111       ssize_t tmp;
112
113       tmp = read (fd, data, datalen);
114
115       if (tmp < 0)
116         {
117           int save_errno = errno;
118           close (fd);
119           errno = save_errno;
120           return GC_RANDOM_ERROR;
121         }
122
123       len += tmp;
124     }
125   while (len < datalen);
126
127   rc = close (fd);
128   if (rc < 0)
129     return GC_RANDOM_ERROR;
130
131   return GC_OK;
132 }
133
134 Gc_rc
135 gc_nonce (char *data, size_t datalen)
136 {
137   return randomize (0, data, datalen);
138 }
139
140 Gc_rc
141 gc_pseudo_random (char *data, size_t datalen)
142 {
143   return randomize (1, data, datalen);
144 }
145
146 Gc_rc
147 gc_random (char *data, size_t datalen)
148 {
149   return randomize (2, data, datalen);
150 }
151
152 /* Memory allocation. */
153
154 void
155 gc_set_allocators (gc_malloc_t func_malloc,
156                    gc_malloc_t secure_malloc,
157                    gc_secure_check_t secure_check,
158                    gc_realloc_t func_realloc, gc_free_t func_free)
159 {
160   return;
161 }
162 /* Ciphers. */
163
164 typedef struct _gc_cipher_ctx {
165   Gc_cipher alg;
166   Gc_cipher_mode mode;
167 #ifdef GC_USE_ARCTWO
168   arctwo_context arctwoContext;
169 #endif
170 #ifdef GC_USE_ARCFOUR
171   arcfour_context arcfourContext;
172 #endif
173 #ifdef GC_USE_DES
174   des_ctx desContext;
175 #endif
176 #ifdef GC_USE_RIJNDAEL
177   rijndaelKeyInstance aesEncKey;
178   rijndaelKeyInstance aesDecKey;
179   rijndaelCipherInstance aesContext;
180 #endif
181 } _gc_cipher_ctx;
182
183 Gc_rc
184 gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode,
185                 gc_cipher_handle * outhandle)
186 {
187   _gc_cipher_ctx *ctx;
188   Gc_rc rc = GC_OK;
189
190   ctx = calloc (sizeof (*ctx), 1);
191
192   ctx->alg = alg;
193   ctx->mode = mode;
194
195   switch (alg)
196     {
197 #ifdef GC_USE_ARCTWO
198     case GC_ARCTWO40:
199       switch (mode)
200         {
201         case GC_ECB:
202           break;
203
204         default:
205           rc = GC_INVALID_CIPHER;
206         }
207       break;
208 #endif
209
210 #ifdef GC_USE_ARCFOUR
211     case GC_ARCFOUR128:
212     case GC_ARCFOUR40:
213       switch (mode)
214         {
215         case GC_STREAM:
216           break;
217
218         default:
219           rc = GC_INVALID_CIPHER;
220         }
221       break;
222 #endif
223
224 #ifdef GC_USE_DES
225     case GC_DES:
226       switch (mode)
227         {
228         case GC_ECB:
229           break;
230
231         default:
232           rc = GC_INVALID_CIPHER;
233         }
234       break;
235 #endif
236
237 #ifdef GC_USE_RIJNDAEL
238     case GC_AES128:
239     case GC_AES192:
240     case GC_AES256:
241       switch (mode)
242         {
243         case GC_ECB:
244         case GC_CBC:
245           break;
246
247         default:
248           rc = GC_INVALID_CIPHER;
249         }
250       break;
251 #endif
252
253     default:
254       rc = GC_INVALID_CIPHER;
255     }
256
257   if (rc == GC_OK)
258     *outhandle = ctx;
259   else
260     free (ctx);
261
262   return rc;
263 }
264
265 Gc_rc
266 gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key)
267 {
268   _gc_cipher_ctx *ctx = handle;
269
270   switch (ctx->alg)
271     {
272 #ifdef GC_USE_ARCTWO
273     case GC_ARCTWO40:
274       arctwo_setkey (&ctx->arctwoContext, keylen, key);
275       break;
276 #endif
277
278 #ifdef GC_USE_ARCFOUR
279     case GC_ARCFOUR128:
280     case GC_ARCFOUR40:
281       arcfour_setkey (&ctx->arcfourContext, key, keylen);
282       break;
283 #endif
284
285 #ifdef GC_USE_DES
286     case GC_DES:
287       if (keylen != 8)
288         return GC_INVALID_CIPHER;
289       des_setkey (&ctx->desContext, key);
290       break;
291 #endif
292
293 #ifdef GC_USE_RIJNDAEL
294     case GC_AES128:
295     case GC_AES192:
296     case GC_AES256:
297       {
298         rijndael_rc rc;
299         size_t i;
300         char keyMaterial[RIJNDAEL_MAX_KEY_SIZE + 1];
301
302         for (i = 0; i < keylen; i++)
303           sprintf (&keyMaterial[2*i], "%02x", key[i] & 0xFF);
304
305         rc = rijndaelMakeKey (&ctx->aesEncKey, RIJNDAEL_DIR_ENCRYPT,
306                               keylen * 8, keyMaterial);
307         if (rc < 0)
308           return GC_INVALID_CIPHER;
309
310         rc = rijndaelMakeKey (&ctx->aesDecKey, RIJNDAEL_DIR_DECRYPT,
311                               keylen * 8, keyMaterial);
312         if (rc < 0)
313           return GC_INVALID_CIPHER;
314
315         rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_ECB, NULL);
316         if (rc < 0)
317           return GC_INVALID_CIPHER;
318       }
319       break;
320 #endif
321
322     default:
323       return GC_INVALID_CIPHER;
324     }
325
326   return GC_OK;
327 }
328
329 Gc_rc
330 gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv)
331 {
332   _gc_cipher_ctx *ctx = handle;
333
334   switch (ctx->alg)
335     {
336 #ifdef GC_USE_RIJNDAEL
337     case GC_AES128:
338     case GC_AES192:
339     case GC_AES256:
340       switch (ctx->mode)
341         {
342         case GC_ECB:
343           /* Doesn't use IV. */
344           break;
345
346         case GC_CBC:
347           {
348             rijndael_rc rc;
349             size_t i;
350             char ivMaterial[2 * RIJNDAEL_MAX_IV_SIZE + 1];
351
352             for (i = 0; i < ivlen; i++)
353               sprintf (&ivMaterial[2*i], "%02x", iv[i] & 0xFF);
354
355             rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_CBC,
356                                      ivMaterial);
357             if (rc < 0)
358               return GC_INVALID_CIPHER;
359           }
360           break;
361
362         default:
363           return GC_INVALID_CIPHER;
364         }
365       break;
366 #endif
367
368     default:
369       return GC_INVALID_CIPHER;
370     }
371
372   return GC_OK;
373 }
374
375 Gc_rc
376 gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data)
377 {
378   _gc_cipher_ctx *ctx = handle;
379
380   switch (ctx->alg)
381     {
382 #ifdef GC_USE_ARCTWO
383     case GC_ARCTWO40:
384       arctwo_encrypt (&ctx->arctwoContext, data, data, len);
385       break;
386 #endif
387
388 #ifdef GC_USE_ARCFOUR
389     case GC_ARCFOUR128:
390     case GC_ARCFOUR40:
391       arcfour_stream (&ctx->arcfourContext, data, data, len);
392       break;
393 #endif
394
395 #ifdef GC_USE_DES
396     case GC_DES:
397       for (; len >= 8; len -= 8, data += 8)
398         des_ecb_encrypt (&ctx->desContext, data, data);
399       break;
400 #endif
401
402 #ifdef GC_USE_RIJNDAEL
403     case GC_AES128:
404     case GC_AES192:
405     case GC_AES256:
406       {
407         int nblocks;
408
409         nblocks = rijndaelBlockEncrypt (&ctx->aesContext, &ctx->aesEncKey,
410                                         data, 8 * len, data);
411         if (nblocks < 0)
412           return GC_INVALID_CIPHER;
413       }
414       break;
415 #endif
416
417     default:
418       return GC_INVALID_CIPHER;
419     }
420
421   return GC_OK;
422 }
423
424 Gc_rc
425 gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data)
426 {
427   _gc_cipher_ctx *ctx = handle;
428
429   switch (ctx->alg)
430     {
431 #ifdef GC_USE_ARCTWO
432     case GC_ARCTWO40:
433       arctwo_decrypt (&ctx->arctwoContext, data, data, len);
434       break;
435 #endif
436
437 #ifdef GC_USE_ARCFOUR
438     case GC_ARCFOUR128:
439     case GC_ARCFOUR40:
440       arcfour_stream (&ctx->arcfourContext, data, data, len);
441       break;
442 #endif
443
444 #ifdef GC_USE_DES
445     case GC_DES:
446       for (; len >= 8; len -= 8, data += 8)
447         des_ecb_decrypt (&ctx->desContext, data, data);
448       break;
449 #endif
450
451 #ifdef GC_USE_RIJNDAEL
452     case GC_AES128:
453     case GC_AES192:
454     case GC_AES256:
455       {
456         int nblocks;
457
458         nblocks = rijndaelBlockDecrypt (&ctx->aesContext, &ctx->aesDecKey,
459                                         data, 8 * len, data);
460         if (nblocks < 0)
461           return GC_INVALID_CIPHER;
462       }
463       break;
464 #endif
465
466     default:
467       return GC_INVALID_CIPHER;
468     }
469
470   return GC_OK;
471 }
472
473 Gc_rc
474 gc_cipher_close (gc_cipher_handle handle)
475 {
476   _gc_cipher_ctx *ctx = handle;
477
478   if (ctx)
479     free (ctx);
480
481   return GC_OK;
482 }
483
484 /* Hashes. */
485
486 Gc_rc
487 gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf)
488 {
489   switch (hash)
490     {
491 #ifdef GC_USE_MD4
492     case GC_MD4:
493       md4_buffer (in, inlen, resbuf);
494       break;
495 #endif
496
497 #ifdef GC_USE_MD5
498     case GC_MD5:
499       md5_buffer (in, inlen, resbuf);
500       break;
501 #endif
502
503 #ifdef GC_USE_SHA1
504     case GC_SHA1:
505       sha1_buffer (in, inlen, resbuf);
506       break;
507 #endif
508
509     default:
510       return GC_INVALID_HASH;
511     }
512
513   return GC_OK;
514 }
515
516 #ifdef GC_USE_MD4
517 Gc_rc
518 gc_md4 (const void *in, size_t inlen, void *resbuf)
519 {
520   md4_buffer (in, inlen, resbuf);
521   return GC_OK;
522 }
523 #endif
524
525 #ifdef GC_USE_MD5
526 Gc_rc
527 gc_md5 (const void *in, size_t inlen, void *resbuf)
528 {
529   md5_buffer (in, inlen, resbuf);
530   return GC_OK;
531 }
532 #endif
533
534 #ifdef GC_USE_SHA1
535 Gc_rc
536 gc_sha1 (const void *in, size_t inlen, void *resbuf)
537 {
538   sha1_buffer (in, inlen, resbuf);
539   return GC_OK;
540 }
541 #endif
542
543 #ifdef GC_USE_HMAC_MD5
544 Gc_rc
545 gc_hmac_md5 (const void *key, size_t keylen,
546              const void *in, size_t inlen, char *resbuf)
547 {
548   hmac_md5 (key, keylen, in, inlen, resbuf);
549   return GC_OK;
550 }
551 #endif
552
553 #ifdef GC_USE_HMAC_SHA1
554 Gc_rc
555 gc_hmac_sha1 (const void *key, size_t keylen,
556               const void *in, size_t inlen, char *resbuf)
557 {
558   hmac_sha1 (key, keylen, in, inlen, resbuf);
559   return GC_OK;
560 }
561 #endif