Add MD2 and hash fixes.
[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_MD2
42 # include "md2.h"
43 #endif
44 #ifdef GC_USE_MD4
45 # include "md4.h"
46 #endif
47 #ifdef GC_USE_MD5
48 # include "md5.h"
49 #endif
50 #ifdef GC_USE_SHA1
51 # include "sha1.h"
52 #endif
53 #ifdef GC_USE_HMAC_MD5
54 # include "hmac.h"
55 #endif
56
57 /* Ciphers. */
58 #ifdef GC_USE_ARCFOUR
59 # include "arcfour.h"
60 #endif
61 #ifdef GC_USE_ARCTWO
62 # include "arctwo.h"
63 #endif
64 #ifdef GC_USE_DES
65 # include "des.h"
66 #endif
67 #ifdef GC_USE_RIJNDAEL
68 # include "rijndael-api-fst.h"
69 #endif
70
71 Gc_rc
72 gc_init (void)
73 {
74   return GC_OK;
75 }
76
77 void
78 gc_done (void)
79 {
80   return;
81 }
82
83 /* Randomness. */
84
85 static Gc_rc
86 randomize (int level, char *data, size_t datalen)
87 {
88   int fd;
89   const char *device;
90   size_t len = 0;
91   int rc;
92
93   switch (level)
94     {
95     case 0:
96       device = NAME_OF_NONCE_DEVICE;
97       break;
98
99     case 1:
100       device = NAME_OF_PSEUDO_RANDOM_DEVICE;
101       break;
102
103     default:
104       device = NAME_OF_RANDOM_DEVICE;
105       break;
106     }
107
108   fd = open (device, O_RDONLY);
109   if (fd < 0)
110     return GC_RANDOM_ERROR;
111
112   do
113     {
114       ssize_t tmp;
115
116       tmp = read (fd, data, datalen);
117
118       if (tmp < 0)
119         {
120           int save_errno = errno;
121           close (fd);
122           errno = save_errno;
123           return GC_RANDOM_ERROR;
124         }
125
126       len += tmp;
127     }
128   while (len < datalen);
129
130   rc = close (fd);
131   if (rc < 0)
132     return GC_RANDOM_ERROR;
133
134   return GC_OK;
135 }
136
137 Gc_rc
138 gc_nonce (char *data, size_t datalen)
139 {
140   return randomize (0, data, datalen);
141 }
142
143 Gc_rc
144 gc_pseudo_random (char *data, size_t datalen)
145 {
146   return randomize (1, data, datalen);
147 }
148
149 Gc_rc
150 gc_random (char *data, size_t datalen)
151 {
152   return randomize (2, data, datalen);
153 }
154
155 /* Memory allocation. */
156
157 void
158 gc_set_allocators (gc_malloc_t func_malloc,
159                    gc_malloc_t secure_malloc,
160                    gc_secure_check_t secure_check,
161                    gc_realloc_t func_realloc, gc_free_t func_free)
162 {
163   return;
164 }
165 /* Ciphers. */
166
167 typedef struct _gc_cipher_ctx {
168   Gc_cipher alg;
169   Gc_cipher_mode mode;
170 #ifdef GC_USE_ARCTWO
171   arctwo_context arctwoContext;
172   char arctwoIV[ARCTWO_BLOCK_SIZE];
173 #endif
174 #ifdef GC_USE_ARCFOUR
175   arcfour_context arcfourContext;
176 #endif
177 #ifdef GC_USE_DES
178   des_ctx desContext;
179 #endif
180 #ifdef GC_USE_RIJNDAEL
181   rijndaelKeyInstance aesEncKey;
182   rijndaelKeyInstance aesDecKey;
183   rijndaelCipherInstance aesContext;
184 #endif
185 } _gc_cipher_ctx;
186
187 Gc_rc
188 gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode,
189                 gc_cipher_handle * outhandle)
190 {
191   _gc_cipher_ctx *ctx;
192   Gc_rc rc = GC_OK;
193
194   ctx = calloc (sizeof (*ctx), 1);
195
196   ctx->alg = alg;
197   ctx->mode = mode;
198
199   switch (alg)
200     {
201 #ifdef GC_USE_ARCTWO
202     case GC_ARCTWO40:
203       switch (mode)
204         {
205         case GC_ECB:
206         case GC_CBC:
207           break;
208
209         default:
210           rc = GC_INVALID_CIPHER;
211         }
212       break;
213 #endif
214
215 #ifdef GC_USE_ARCFOUR
216     case GC_ARCFOUR128:
217     case GC_ARCFOUR40:
218       switch (mode)
219         {
220         case GC_STREAM:
221           break;
222
223         default:
224           rc = GC_INVALID_CIPHER;
225         }
226       break;
227 #endif
228
229 #ifdef GC_USE_DES
230     case GC_DES:
231       switch (mode)
232         {
233         case GC_ECB:
234           break;
235
236         default:
237           rc = GC_INVALID_CIPHER;
238         }
239       break;
240 #endif
241
242 #ifdef GC_USE_RIJNDAEL
243     case GC_AES128:
244     case GC_AES192:
245     case GC_AES256:
246       switch (mode)
247         {
248         case GC_ECB:
249         case GC_CBC:
250           break;
251
252         default:
253           rc = GC_INVALID_CIPHER;
254         }
255       break;
256 #endif
257
258     default:
259       rc = GC_INVALID_CIPHER;
260     }
261
262   if (rc == GC_OK)
263     *outhandle = ctx;
264   else
265     free (ctx);
266
267   return rc;
268 }
269
270 Gc_rc
271 gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key)
272 {
273   _gc_cipher_ctx *ctx = handle;
274
275   switch (ctx->alg)
276     {
277 #ifdef GC_USE_ARCTWO
278     case GC_ARCTWO40:
279       arctwo_setkey (&ctx->arctwoContext, keylen, key);
280       break;
281 #endif
282
283 #ifdef GC_USE_ARCFOUR
284     case GC_ARCFOUR128:
285     case GC_ARCFOUR40:
286       arcfour_setkey (&ctx->arcfourContext, key, keylen);
287       break;
288 #endif
289
290 #ifdef GC_USE_DES
291     case GC_DES:
292       if (keylen != 8)
293         return GC_INVALID_CIPHER;
294       des_setkey (&ctx->desContext, key);
295       break;
296 #endif
297
298 #ifdef GC_USE_RIJNDAEL
299     case GC_AES128:
300     case GC_AES192:
301     case GC_AES256:
302       {
303         rijndael_rc rc;
304         size_t i;
305         char keyMaterial[RIJNDAEL_MAX_KEY_SIZE + 1];
306
307         for (i = 0; i < keylen; i++)
308           sprintf (&keyMaterial[2*i], "%02x", key[i] & 0xFF);
309
310         rc = rijndaelMakeKey (&ctx->aesEncKey, RIJNDAEL_DIR_ENCRYPT,
311                               keylen * 8, keyMaterial);
312         if (rc < 0)
313           return GC_INVALID_CIPHER;
314
315         rc = rijndaelMakeKey (&ctx->aesDecKey, RIJNDAEL_DIR_DECRYPT,
316                               keylen * 8, keyMaterial);
317         if (rc < 0)
318           return GC_INVALID_CIPHER;
319
320         rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_ECB, NULL);
321         if (rc < 0)
322           return GC_INVALID_CIPHER;
323       }
324       break;
325 #endif
326
327     default:
328       return GC_INVALID_CIPHER;
329     }
330
331   return GC_OK;
332 }
333
334 Gc_rc
335 gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv)
336 {
337   _gc_cipher_ctx *ctx = handle;
338
339   switch (ctx->alg)
340     {
341 #ifdef GC_USE_ARCTWO
342     case GC_ARCTWO40:
343       if (ivlen != ARCTWO_BLOCK_SIZE)
344         return GC_INVALID_CIPHER;
345       memcpy (ctx->arctwoIV, iv, ivlen);
346       break;
347 #endif
348
349 #ifdef GC_USE_RIJNDAEL
350     case GC_AES128:
351     case GC_AES192:
352     case GC_AES256:
353       switch (ctx->mode)
354         {
355         case GC_ECB:
356           /* Doesn't use IV. */
357           break;
358
359         case GC_CBC:
360           {
361             rijndael_rc rc;
362             size_t i;
363             char ivMaterial[2 * RIJNDAEL_MAX_IV_SIZE + 1];
364
365             for (i = 0; i < ivlen; i++)
366               sprintf (&ivMaterial[2*i], "%02x", iv[i] & 0xFF);
367
368             rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_CBC,
369                                      ivMaterial);
370             if (rc < 0)
371               return GC_INVALID_CIPHER;
372           }
373           break;
374
375         default:
376           return GC_INVALID_CIPHER;
377         }
378       break;
379 #endif
380
381     default:
382       return GC_INVALID_CIPHER;
383     }
384
385   return GC_OK;
386 }
387
388 Gc_rc
389 gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data)
390 {
391   _gc_cipher_ctx *ctx = handle;
392
393   switch (ctx->alg)
394     {
395 #ifdef GC_USE_ARCTWO
396     case GC_ARCTWO40:
397       switch (ctx->mode)
398         {
399         case GC_ECB:
400           arctwo_encrypt (&ctx->arctwoContext, data, data, len);
401           break;
402
403         case GC_CBC:
404           for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE,
405                  data += ARCTWO_BLOCK_SIZE)
406             {
407               size_t i;
408               for (i = 0; i < ARCTWO_BLOCK_SIZE; i++)
409                 data[i] ^= ctx->arctwoIV[i];
410               arctwo_encrypt (&ctx->arctwoContext, data, data,
411                               ARCTWO_BLOCK_SIZE);
412               memcpy (ctx->arctwoIV, data, ARCTWO_BLOCK_SIZE);
413             }
414             break;
415
416         default:
417           return GC_INVALID_CIPHER;
418         }
419       break;
420 #endif
421
422 #ifdef GC_USE_ARCFOUR
423     case GC_ARCFOUR128:
424     case GC_ARCFOUR40:
425       arcfour_stream (&ctx->arcfourContext, data, data, len);
426       break;
427 #endif
428
429 #ifdef GC_USE_DES
430     case GC_DES:
431       for (; len >= 8; len -= 8, data += 8)
432         des_ecb_encrypt (&ctx->desContext, data, data);
433       break;
434 #endif
435
436 #ifdef GC_USE_RIJNDAEL
437     case GC_AES128:
438     case GC_AES192:
439     case GC_AES256:
440       {
441         int nblocks;
442
443         nblocks = rijndaelBlockEncrypt (&ctx->aesContext, &ctx->aesEncKey,
444                                         data, 8 * len, data);
445         if (nblocks < 0)
446           return GC_INVALID_CIPHER;
447       }
448       break;
449 #endif
450
451     default:
452       return GC_INVALID_CIPHER;
453     }
454
455   return GC_OK;
456 }
457
458 Gc_rc
459 gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data)
460 {
461   _gc_cipher_ctx *ctx = handle;
462
463   switch (ctx->alg)
464     {
465 #ifdef GC_USE_ARCTWO
466     case GC_ARCTWO40:
467       switch (ctx->mode)
468         {
469         case GC_ECB:
470           arctwo_decrypt (&ctx->arctwoContext, data, data, len);
471           break;
472
473         case GC_CBC:
474           for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE,
475                  data += ARCTWO_BLOCK_SIZE)
476             {
477               char tmpIV[ARCTWO_BLOCK_SIZE];
478               size_t i;
479               memcpy (tmpIV, data, ARCTWO_BLOCK_SIZE);
480               arctwo_decrypt (&ctx->arctwoContext, data, data,
481                               ARCTWO_BLOCK_SIZE);
482               for (i = 0; i < ARCTWO_BLOCK_SIZE; i++)
483                 data[i] ^= ctx->arctwoIV[i];
484               memcpy (ctx->arctwoIV, tmpIV, ARCTWO_BLOCK_SIZE);
485             }
486           break;
487
488         default:
489           return GC_INVALID_CIPHER;
490         }
491       break;
492 #endif
493
494 #ifdef GC_USE_ARCFOUR
495     case GC_ARCFOUR128:
496     case GC_ARCFOUR40:
497       arcfour_stream (&ctx->arcfourContext, data, data, len);
498       break;
499 #endif
500
501 #ifdef GC_USE_DES
502     case GC_DES:
503       for (; len >= 8; len -= 8, data += 8)
504         des_ecb_decrypt (&ctx->desContext, data, data);
505       break;
506 #endif
507
508 #ifdef GC_USE_RIJNDAEL
509     case GC_AES128:
510     case GC_AES192:
511     case GC_AES256:
512       {
513         int nblocks;
514
515         nblocks = rijndaelBlockDecrypt (&ctx->aesContext, &ctx->aesDecKey,
516                                         data, 8 * len, data);
517         if (nblocks < 0)
518           return GC_INVALID_CIPHER;
519       }
520       break;
521 #endif
522
523     default:
524       return GC_INVALID_CIPHER;
525     }
526
527   return GC_OK;
528 }
529
530 Gc_rc
531 gc_cipher_close (gc_cipher_handle handle)
532 {
533   _gc_cipher_ctx *ctx = handle;
534
535   if (ctx)
536     free (ctx);
537
538   return GC_OK;
539 }
540
541 /* Hashes. */
542
543 #define MAX_DIGEST_SIZE 20
544
545 typedef struct _gc_hash_ctx {
546   Gc_hash alg;
547   Gc_hash_mode mode;
548   char hash[MAX_DIGEST_SIZE];
549 #ifdef GC_USE_MD2
550   struct md2_ctx md2Context;
551 #endif
552 #ifdef GC_USE_MD4
553   struct md4_ctx md4Context;
554 #endif
555 #ifdef GC_USE_MD5
556   struct md5_ctx md5Context;
557 #endif
558 #ifdef GC_USE_SHA1
559   struct sha1_ctx sha1Context;
560 #endif
561 } _gc_hash_ctx;
562
563 Gc_rc
564 gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle)
565 {
566   _gc_hash_ctx *ctx;
567   Gc_rc rc = GC_OK;
568
569   ctx = calloc (sizeof (*ctx), 1);
570
571   ctx->alg = hash;
572   ctx->mode = mode;
573
574   switch (hash)
575     {
576 #ifdef GC_USE_MD2
577     case GC_MD2:
578       md2_init_ctx (&ctx->md2Context);
579       break;
580 #endif
581
582 #ifdef GC_USE_MD4
583     case GC_MD4:
584       md4_init_ctx (&ctx->md4Context);
585       break;
586 #endif
587
588 #ifdef GC_USE_MD5
589     case GC_MD5:
590       md5_init_ctx (&ctx->md5Context);
591       break;
592 #endif
593
594 #ifdef GC_USE_SHA1
595     case GC_SHA1:
596       sha1_init_ctx (&ctx->sha1Context);
597       break;
598 #endif
599
600     default:
601       rc = GC_INVALID_HASH;
602       break;
603     }
604
605   switch (mode)
606     {
607     case 0:
608       break;
609
610     default:
611       rc = GC_INVALID_HASH;
612       break;
613     }
614
615   if (rc == GC_OK)
616     *outhandle = ctx;
617   else
618     free (ctx);
619
620   return rc;
621 }
622
623 Gc_rc
624 gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle)
625 {
626   _gc_hash_ctx *in = handle;
627   _gc_hash_ctx *out;
628
629   *outhandle = out = calloc (sizeof (*out), 1);
630   if (!out)
631     return GC_MALLOC_ERROR;
632
633   memcpy (out, in, sizeof (*out));
634
635   return GC_OK;
636 }
637
638 size_t
639 gc_hash_digest_length (Gc_hash hash)
640 {
641   size_t len;
642
643   switch (hash)
644     {
645     case GC_MD2:
646       len = GC_MD2_DIGEST_SIZE;
647       break;
648
649     case GC_MD4:
650       len = GC_MD4_DIGEST_SIZE;
651       break;
652
653     case GC_MD5:
654       len = GC_MD5_DIGEST_SIZE;
655       break;
656
657     case GC_RMD160:
658       len = GC_RMD160_DIGEST_SIZE;
659       break;
660
661     case GC_SHA1:
662       len = GC_SHA1_DIGEST_SIZE;
663       break;
664
665     default:
666       return 0;
667     }
668
669   return len;
670 }
671
672 void
673 gc_hash_write (gc_hash_handle handle, size_t len, const char *data)
674 {
675   _gc_hash_ctx *ctx = handle;
676
677   switch (ctx->alg)
678     {
679 #ifdef GC_USE_MD2
680     case GC_MD2:
681       md2_process_bytes (data, len, &ctx->md2Context);
682       break;
683 #endif
684
685 #ifdef GC_USE_MD4
686     case GC_MD4:
687       md4_process_bytes (data, len, &ctx->md4Context);
688       break;
689 #endif
690
691 #ifdef GC_USE_MD5
692     case GC_MD5:
693       md5_process_bytes (data, len, &ctx->md5Context);
694       break;
695 #endif
696
697 #ifdef GC_USE_SHA1
698     case GC_SHA1:
699       sha1_process_bytes (data, len, &ctx->sha1Context);
700       break;
701 #endif
702
703     default:
704       break;
705     }
706 }
707
708 const char *
709 gc_hash_read (gc_hash_handle handle)
710 {
711   _gc_hash_ctx *ctx = handle;
712   const char *ret = NULL;
713
714   switch (ctx->alg)
715     {
716 #ifdef GC_USE_MD2
717     case GC_MD2:
718       md2_finish_ctx (&ctx->md2Context, ctx->hash);
719       ret = ctx->hash;
720       break;
721 #endif
722
723 #ifdef GC_USE_MD4
724     case GC_MD4:
725       md4_finish_ctx (&ctx->md4Context, ctx->hash);
726       ret = ctx->hash;
727       break;
728 #endif
729
730 #ifdef GC_USE_MD5
731     case GC_MD5:
732       md5_finish_ctx (&ctx->md5Context, ctx->hash);
733       ret = ctx->hash;
734       break;
735 #endif
736
737 #ifdef GC_USE_SHA1
738     case GC_SHA1:
739       sha1_finish_ctx (&ctx->sha1Context, ctx->hash);
740       ret = ctx->hash;
741       break;
742 #endif
743
744     default:
745       return NULL;
746     }
747
748   return ret;
749 }
750
751 void
752 gc_hash_close (gc_hash_handle handle)
753 {
754   _gc_hash_ctx *ctx = handle;
755
756   free (ctx);
757 }
758
759 Gc_rc
760 gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf)
761 {
762   switch (hash)
763     {
764 #ifdef GC_USE_MD2
765     case GC_MD2:
766       md2_buffer (in, inlen, resbuf);
767       break;
768 #endif
769
770 #ifdef GC_USE_MD4
771     case GC_MD4:
772       md4_buffer (in, inlen, resbuf);
773       break;
774 #endif
775
776 #ifdef GC_USE_MD5
777     case GC_MD5:
778       md5_buffer (in, inlen, resbuf);
779       break;
780 #endif
781
782 #ifdef GC_USE_SHA1
783     case GC_SHA1:
784       sha1_buffer (in, inlen, resbuf);
785       break;
786 #endif
787
788     default:
789       return GC_INVALID_HASH;
790     }
791
792   return GC_OK;
793 }
794
795 #ifdef GC_USE_MD2
796 Gc_rc
797 gc_md2 (const void *in, size_t inlen, void *resbuf)
798 {
799   md2_buffer (in, inlen, resbuf);
800   return GC_OK;
801 }
802 #endif
803
804 #ifdef GC_USE_MD4
805 Gc_rc
806 gc_md4 (const void *in, size_t inlen, void *resbuf)
807 {
808   md4_buffer (in, inlen, resbuf);
809   return GC_OK;
810 }
811 #endif
812
813 #ifdef GC_USE_MD5
814 Gc_rc
815 gc_md5 (const void *in, size_t inlen, void *resbuf)
816 {
817   md5_buffer (in, inlen, resbuf);
818   return GC_OK;
819 }
820 #endif
821
822 #ifdef GC_USE_SHA1
823 Gc_rc
824 gc_sha1 (const void *in, size_t inlen, void *resbuf)
825 {
826   sha1_buffer (in, inlen, resbuf);
827   return GC_OK;
828 }
829 #endif
830
831 #ifdef GC_USE_HMAC_MD5
832 Gc_rc
833 gc_hmac_md5 (const void *key, size_t keylen,
834              const void *in, size_t inlen, char *resbuf)
835 {
836   hmac_md5 (key, keylen, in, inlen, resbuf);
837   return GC_OK;
838 }
839 #endif
840
841 #ifdef GC_USE_HMAC_SHA1
842 Gc_rc
843 gc_hmac_sha1 (const void *key, size_t keylen,
844               const void *in, size_t inlen, char *resbuf)
845 {
846   hmac_sha1 (key, keylen, in, inlen, resbuf);
847   return GC_OK;
848 }
849 #endif