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