Move module indicator macros from *.m4 files to the module descriptions.
[gnulib.git] / lib / gc-libgcrypt.c
1 /* gc-libgcrypt.c --- Crypto wrappers around Libgcrypt for GC.
2  * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007  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 Libgcrypt. */
22
23 #include <config.h>
24
25 /* Get prototype. */
26 #include "gc.h"
27
28 #include <stdlib.h>
29 #include <string.h>
30
31 /* Get libgcrypt API. */
32 #include <gcrypt.h>
33 #ifdef GNULIB_GC_MD2
34 # include "md2.h"
35 #endif
36
37 #include <assert.h>
38
39 /* Initialization. */
40
41 Gc_rc
42 gc_init (void)
43 {
44   gcry_error_t err;
45
46   err = gcry_control (GCRYCTL_ANY_INITIALIZATION_P);
47   if (err == GPG_ERR_NO_ERROR)
48     {
49       if (gcry_check_version (GCRYPT_VERSION) == NULL)
50         return GC_INIT_ERROR;
51
52       err = gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL, 0);
53       if (err != GPG_ERR_NO_ERROR)
54         return GC_INIT_ERROR;
55     }
56
57   return GC_OK;
58 }
59
60 void
61 gc_done (void)
62 {
63   return;
64 }
65
66 #ifdef GNULIB_GC_RANDOM
67
68 /* Randomness. */
69
70 Gc_rc
71 gc_nonce (char *data, size_t datalen)
72 {
73   gcry_create_nonce ((unsigned char *) data, datalen);
74   return GC_OK;
75 }
76
77 Gc_rc
78 gc_pseudo_random (char *data, size_t datalen)
79 {
80   gcry_randomize ((unsigned char *) data, datalen, GCRY_STRONG_RANDOM);
81   return GC_OK;
82 }
83
84 Gc_rc
85 gc_random (char *data, size_t datalen)
86 {
87   gcry_randomize ((unsigned char *) data, datalen, GCRY_VERY_STRONG_RANDOM);
88   return GC_OK;
89 }
90
91 #endif
92
93 /* Memory allocation. */
94
95 void
96 gc_set_allocators (gc_malloc_t func_malloc,
97                    gc_malloc_t secure_malloc,
98                    gc_secure_check_t secure_check,
99                    gc_realloc_t func_realloc, gc_free_t func_free)
100 {
101   gcry_set_allocation_handler (func_malloc, secure_malloc, secure_check,
102                                func_realloc, func_free);
103 }
104
105 /* Ciphers. */
106
107 Gc_rc
108 gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode,
109                 gc_cipher_handle * outhandle)
110 {
111   int gcryalg, gcrymode;
112   gcry_error_t err;
113
114   switch (alg)
115     {
116     case GC_AES128:
117       gcryalg = GCRY_CIPHER_RIJNDAEL;
118       break;
119
120     case GC_AES192:
121       gcryalg = GCRY_CIPHER_RIJNDAEL;
122       break;
123
124     case GC_AES256:
125       gcryalg = GCRY_CIPHER_RIJNDAEL256;
126       break;
127
128     case GC_3DES:
129       gcryalg = GCRY_CIPHER_3DES;
130       break;
131
132     case GC_DES:
133       gcryalg = GCRY_CIPHER_DES;
134       break;
135
136     case GC_ARCFOUR128:
137     case GC_ARCFOUR40:
138       gcryalg = GCRY_CIPHER_ARCFOUR;
139       break;
140
141     case GC_ARCTWO40:
142       gcryalg = GCRY_CIPHER_RFC2268_40;
143       break;
144
145     default:
146       return GC_INVALID_CIPHER;
147     }
148
149   switch (mode)
150     {
151     case GC_ECB:
152       gcrymode = GCRY_CIPHER_MODE_ECB;
153       break;
154
155     case GC_CBC:
156       gcrymode = GCRY_CIPHER_MODE_CBC;
157       break;
158
159     case GC_STREAM:
160       gcrymode = GCRY_CIPHER_MODE_STREAM;
161       break;
162
163     default:
164       return GC_INVALID_CIPHER;
165     }
166
167   err = gcry_cipher_open ((gcry_cipher_hd_t *) outhandle,
168                           gcryalg, gcrymode, 0);
169   if (gcry_err_code (err))
170     return GC_INVALID_CIPHER;
171
172   return GC_OK;
173 }
174
175 Gc_rc
176 gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key)
177 {
178   gcry_error_t err;
179
180   err = gcry_cipher_setkey ((gcry_cipher_hd_t) handle, key, keylen);
181   if (gcry_err_code (err))
182     return GC_INVALID_CIPHER;
183
184   return GC_OK;
185 }
186
187 Gc_rc
188 gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv)
189 {
190   gcry_error_t err;
191
192   err = gcry_cipher_setiv ((gcry_cipher_hd_t) handle, iv, ivlen);
193   if (gcry_err_code (err))
194     return GC_INVALID_CIPHER;
195
196   return GC_OK;
197 }
198
199 Gc_rc
200 gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data)
201 {
202   if (gcry_cipher_encrypt ((gcry_cipher_hd_t) handle,
203                            data, len, NULL, len) != 0)
204     return GC_INVALID_CIPHER;
205
206   return GC_OK;
207 }
208
209 Gc_rc
210 gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data)
211 {
212   if (gcry_cipher_decrypt ((gcry_cipher_hd_t) handle,
213                            data, len, NULL, len) != 0)
214     return GC_INVALID_CIPHER;
215
216   return GC_OK;
217 }
218
219 Gc_rc
220 gc_cipher_close (gc_cipher_handle handle)
221 {
222   gcry_cipher_close (handle);
223
224   return GC_OK;
225 }
226
227 /* Hashes. */
228
229 typedef struct _gc_hash_ctx {
230   Gc_hash alg;
231   Gc_hash_mode mode;
232   gcry_md_hd_t gch;
233 #ifdef GNULIB_GC_MD2
234   char hash[GC_MD2_DIGEST_SIZE];
235   struct md2_ctx md2Context;
236 #endif
237 } _gc_hash_ctx;
238
239 Gc_rc
240 gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle)
241 {
242   _gc_hash_ctx *ctx;
243   int gcryalg, gcrymode;
244   gcry_error_t err;
245   Gc_rc rc = GC_OK;
246
247   ctx = calloc (sizeof (*ctx), 1);
248   if (!ctx)
249     return GC_MALLOC_ERROR;
250
251   ctx->alg = hash;
252   ctx->mode = mode;
253
254   switch (hash)
255     {
256     case GC_MD2:
257       gcryalg = GCRY_MD_NONE;
258       break;
259
260     case GC_MD4:
261       gcryalg = GCRY_MD_MD4;
262       break;
263
264     case GC_MD5:
265       gcryalg = GCRY_MD_MD5;
266       break;
267
268     case GC_SHA1:
269       gcryalg = GCRY_MD_SHA1;
270       break;
271
272     case GC_RMD160:
273       gcryalg = GCRY_MD_RMD160;
274       break;
275
276     default:
277       rc = GC_INVALID_HASH;
278     }
279
280   switch (mode)
281     {
282     case 0:
283       gcrymode = 0;
284       break;
285
286     case GC_HMAC:
287       gcrymode = GCRY_MD_FLAG_HMAC;
288       break;
289
290     default:
291       rc = GC_INVALID_HASH;
292     }
293
294   if (rc == GC_OK && gcryalg != GCRY_MD_NONE)
295     {
296       err = gcry_md_open (&ctx->gch, gcryalg, gcrymode);
297       if (gcry_err_code (err))
298         rc = GC_INVALID_HASH;
299     }
300
301   if (rc == GC_OK)
302     *outhandle = ctx;
303   else
304     free (ctx);
305
306   return rc;
307 }
308
309 Gc_rc
310 gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle)
311 {
312   _gc_hash_ctx *in = handle;
313   _gc_hash_ctx *out;
314   int err;
315
316   *outhandle = out = calloc (sizeof (*out), 1);
317   if (!out)
318     return GC_MALLOC_ERROR;
319
320   memcpy (out, in, sizeof (*out));
321
322   err = gcry_md_copy (&out->gch, in->gch);
323   if (err)
324     {
325       free (out);
326       return GC_INVALID_HASH;
327     }
328
329   return GC_OK;
330 }
331
332 size_t
333 gc_hash_digest_length (Gc_hash hash)
334 {
335   size_t len;
336
337   switch (hash)
338     {
339     case GC_MD2:
340       len = GC_MD2_DIGEST_SIZE;
341       break;
342
343     case GC_MD4:
344       len = GC_MD4_DIGEST_SIZE;
345       break;
346
347     case GC_MD5:
348       len = GC_MD5_DIGEST_SIZE;
349       break;
350
351     case GC_RMD160:
352       len = GC_RMD160_DIGEST_SIZE;
353       break;
354
355     case GC_SHA1:
356       len = GC_SHA1_DIGEST_SIZE;
357       break;
358
359     default:
360       return 0;
361     }
362
363   return len;
364 }
365
366 void
367 gc_hash_hmac_setkey (gc_hash_handle handle, size_t len, const char *key)
368 {
369   _gc_hash_ctx *ctx = handle;
370 #ifdef GNULIB_GC_MD2
371   if (ctx->alg != GC_MD2)
372 #endif
373     gcry_md_setkey (ctx->gch, key, len);
374 }
375
376 void
377 gc_hash_write (gc_hash_handle handle, size_t len, const char *data)
378 {
379   _gc_hash_ctx *ctx = handle;
380
381 #ifdef GNULIB_GC_MD2
382   if (ctx->alg == GC_MD2)
383     md2_process_bytes (data, len, &ctx->md2Context);
384   else
385 #endif
386     gcry_md_write (ctx->gch, data, len);
387 }
388
389 const char *
390 gc_hash_read (gc_hash_handle handle)
391 {
392   _gc_hash_ctx *ctx = handle;
393   const char *digest;
394
395 #ifdef GNULIB_GC_MD2
396   if (ctx->alg == GC_MD2)
397     {
398       md2_finish_ctx (&ctx->md2Context, ctx->hash);
399       digest = ctx->hash;
400     }
401   else
402 #endif
403     {
404       gcry_md_final (ctx->gch);
405       digest = gcry_md_read (ctx->gch, 0);
406     }
407
408   return digest;
409 }
410
411 void
412 gc_hash_close (gc_hash_handle handle)
413 {
414   _gc_hash_ctx *ctx = handle;
415
416 #ifdef GNULIB_GC_MD2
417   if (ctx->alg != GC_MD2)
418 #endif
419     gcry_md_close (ctx->gch);
420
421   free (ctx);
422 }
423
424 Gc_rc
425 gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf)
426 {
427   int gcryalg;
428
429   switch (hash)
430     {
431 #ifdef GNULIB_GC_MD2
432     case GC_MD2:
433       md2_buffer (in, inlen, resbuf);
434       return GC_OK;
435       break;
436 #endif
437
438 #ifdef GNULIB_GC_MD4
439     case GC_MD4:
440       gcryalg = GCRY_MD_MD4;
441       break;
442 #endif
443
444 #ifdef GNULIB_GC_MD5
445     case GC_MD5:
446       gcryalg = GCRY_MD_MD5;
447       break;
448 #endif
449
450 #ifdef GNULIB_GC_SHA1
451     case GC_SHA1:
452       gcryalg = GCRY_MD_SHA1;
453       break;
454 #endif
455
456 #ifdef GNULIB_GC_RMD160
457     case GC_RMD160:
458       gcryalg = GCRY_MD_RMD160;
459       break;
460 #endif
461
462     default:
463       return GC_INVALID_HASH;
464     }
465
466   gcry_md_hash_buffer (gcryalg, resbuf, in, inlen);
467
468   return GC_OK;
469 }
470
471 /* One-call interface. */
472
473 #ifdef GNULIB_GC_MD2
474 Gc_rc
475 gc_md2 (const void *in, size_t inlen, void *resbuf)
476 {
477   md2_buffer (in, inlen, resbuf);
478   return GC_OK;
479 }
480 #endif
481
482 #ifdef GNULIB_GC_MD4
483 Gc_rc
484 gc_md4 (const void *in, size_t inlen, void *resbuf)
485 {
486   size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_MD4);
487   gcry_md_hd_t hd;
488   gpg_error_t err;
489   unsigned char *p;
490
491   assert (outlen == GC_MD4_DIGEST_SIZE);
492
493   err = gcry_md_open (&hd, GCRY_MD_MD4, 0);
494   if (err != GPG_ERR_NO_ERROR)
495     return GC_INVALID_HASH;
496
497   gcry_md_write (hd, in, inlen);
498
499   p = gcry_md_read (hd, GCRY_MD_MD4);
500   if (p == NULL)
501     {
502       gcry_md_close (hd);
503       return GC_INVALID_HASH;
504     }
505
506   memcpy (resbuf, p, outlen);
507
508   gcry_md_close (hd);
509
510   return GC_OK;
511 }
512 #endif
513
514 #ifdef GNULIB_GC_MD5
515 Gc_rc
516 gc_md5 (const void *in, size_t inlen, void *resbuf)
517 {
518   size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_MD5);
519   gcry_md_hd_t hd;
520   gpg_error_t err;
521   unsigned char *p;
522
523   assert (outlen == GC_MD5_DIGEST_SIZE);
524
525   err = gcry_md_open (&hd, GCRY_MD_MD5, 0);
526   if (err != GPG_ERR_NO_ERROR)
527     return GC_INVALID_HASH;
528
529   gcry_md_write (hd, in, inlen);
530
531   p = gcry_md_read (hd, GCRY_MD_MD5);
532   if (p == NULL)
533     {
534       gcry_md_close (hd);
535       return GC_INVALID_HASH;
536     }
537
538   memcpy (resbuf, p, outlen);
539
540   gcry_md_close (hd);
541
542   return GC_OK;
543 }
544 #endif
545
546 #ifdef GNULIB_GC_SHA1
547 Gc_rc
548 gc_sha1 (const void *in, size_t inlen, void *resbuf)
549 {
550   size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
551   gcry_md_hd_t hd;
552   gpg_error_t err;
553   unsigned char *p;
554
555   assert (outlen == GC_SHA1_DIGEST_SIZE);
556
557   err = gcry_md_open (&hd, GCRY_MD_SHA1, 0);
558   if (err != GPG_ERR_NO_ERROR)
559     return GC_INVALID_HASH;
560
561   gcry_md_write (hd, in, inlen);
562
563   p = gcry_md_read (hd, GCRY_MD_SHA1);
564   if (p == NULL)
565     {
566       gcry_md_close (hd);
567       return GC_INVALID_HASH;
568     }
569
570   memcpy (resbuf, p, outlen);
571
572   gcry_md_close (hd);
573
574   return GC_OK;
575 }
576 #endif
577
578 #ifdef GNULIB_GC_HMAC_MD5
579 Gc_rc
580 gc_hmac_md5 (const void *key, size_t keylen,
581              const void *in, size_t inlen, char *resbuf)
582 {
583   size_t hlen = gcry_md_get_algo_dlen (GCRY_MD_MD5);
584   gcry_md_hd_t mdh;
585   unsigned char *hash;
586   gpg_error_t err;
587
588   assert (hlen == 16);
589
590   err = gcry_md_open (&mdh, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC);
591   if (err != GPG_ERR_NO_ERROR)
592     return GC_INVALID_HASH;
593
594   err = gcry_md_setkey (mdh, key, keylen);
595   if (err != GPG_ERR_NO_ERROR)
596     {
597       gcry_md_close (mdh);
598       return GC_INVALID_HASH;
599     }
600
601   gcry_md_write (mdh, in, inlen);
602
603   hash = gcry_md_read (mdh, GCRY_MD_MD5);
604   if (hash == NULL)
605     {
606       gcry_md_close (mdh);
607       return GC_INVALID_HASH;
608     }
609
610   memcpy (resbuf, hash, hlen);
611
612   gcry_md_close (mdh);
613
614   return GC_OK;
615 }
616 #endif
617
618 #ifdef GNULIB_GC_HMAC_SHA1
619 Gc_rc
620 gc_hmac_sha1 (const void *key, size_t keylen,
621               const void *in, size_t inlen, char *resbuf)
622 {
623   size_t hlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
624   gcry_md_hd_t mdh;
625   unsigned char *hash;
626   gpg_error_t err;
627
628   assert (hlen == GC_SHA1_DIGEST_SIZE);
629
630   err = gcry_md_open (&mdh, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC);
631   if (err != GPG_ERR_NO_ERROR)
632     return GC_INVALID_HASH;
633
634   err = gcry_md_setkey (mdh, key, keylen);
635   if (err != GPG_ERR_NO_ERROR)
636     {
637       gcry_md_close (mdh);
638       return GC_INVALID_HASH;
639     }
640
641   gcry_md_write (mdh, in, inlen);
642
643   hash = gcry_md_read (mdh, GCRY_MD_SHA1);
644   if (hash == NULL)
645     {
646       gcry_md_close (mdh);
647       return GC_INVALID_HASH;
648     }
649
650   memcpy (resbuf, hash, hlen);
651
652   gcry_md_close (mdh);
653
654   return GC_OK;
655 }
656 #endif