lib/gc.h, lib/gc-libgcrypt.c: Support SHA-256/384/512.
[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_SHA256:
273       gcryalg = GCRY_MD_SHA256;
274       break;
275
276     case GC_SHA384:
277       gcryalg = GCRY_MD_SHA384;
278       break;
279
280     case GC_SHA512:
281       gcryalg = GCRY_MD_SHA512;
282       break;
283
284     case GC_RMD160:
285       gcryalg = GCRY_MD_RMD160;
286       break;
287
288     default:
289       rc = GC_INVALID_HASH;
290     }
291
292   switch (mode)
293     {
294     case 0:
295       gcrymode = 0;
296       break;
297
298     case GC_HMAC:
299       gcrymode = GCRY_MD_FLAG_HMAC;
300       break;
301
302     default:
303       rc = GC_INVALID_HASH;
304     }
305
306   if (rc == GC_OK && gcryalg != GCRY_MD_NONE)
307     {
308       err = gcry_md_open (&ctx->gch, gcryalg, gcrymode);
309       if (gcry_err_code (err))
310         rc = GC_INVALID_HASH;
311     }
312
313   if (rc == GC_OK)
314     *outhandle = ctx;
315   else
316     free (ctx);
317
318   return rc;
319 }
320
321 Gc_rc
322 gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle)
323 {
324   _gc_hash_ctx *in = handle;
325   _gc_hash_ctx *out;
326   int err;
327
328   *outhandle = out = calloc (sizeof (*out), 1);
329   if (!out)
330     return GC_MALLOC_ERROR;
331
332   memcpy (out, in, sizeof (*out));
333
334   err = gcry_md_copy (&out->gch, in->gch);
335   if (err)
336     {
337       free (out);
338       return GC_INVALID_HASH;
339     }
340
341   return GC_OK;
342 }
343
344 size_t
345 gc_hash_digest_length (Gc_hash hash)
346 {
347   size_t len;
348
349   switch (hash)
350     {
351     case GC_MD2:
352       len = GC_MD2_DIGEST_SIZE;
353       break;
354
355     case GC_MD4:
356       len = GC_MD4_DIGEST_SIZE;
357       break;
358
359     case GC_MD5:
360       len = GC_MD5_DIGEST_SIZE;
361       break;
362
363     case GC_RMD160:
364       len = GC_RMD160_DIGEST_SIZE;
365       break;
366
367     case GC_SHA1:
368       len = GC_SHA1_DIGEST_SIZE;
369       break;
370
371     case GC_SHA256:
372       len = GC_SHA256_DIGEST_SIZE;
373       break;
374
375     case GC_SHA384:
376       len = GC_SHA384_DIGEST_SIZE;
377       break;
378
379     case GC_SHA512:
380       len = GC_SHA512_DIGEST_SIZE;
381       break;
382
383     default:
384       return 0;
385     }
386
387   return len;
388 }
389
390 void
391 gc_hash_hmac_setkey (gc_hash_handle handle, size_t len, const char *key)
392 {
393   _gc_hash_ctx *ctx = handle;
394 #ifdef GNULIB_GC_MD2
395   if (ctx->alg != GC_MD2)
396 #endif
397     gcry_md_setkey (ctx->gch, key, len);
398 }
399
400 void
401 gc_hash_write (gc_hash_handle handle, size_t len, const char *data)
402 {
403   _gc_hash_ctx *ctx = handle;
404
405 #ifdef GNULIB_GC_MD2
406   if (ctx->alg == GC_MD2)
407     md2_process_bytes (data, len, &ctx->md2Context);
408   else
409 #endif
410     gcry_md_write (ctx->gch, data, len);
411 }
412
413 const char *
414 gc_hash_read (gc_hash_handle handle)
415 {
416   _gc_hash_ctx *ctx = handle;
417   const char *digest;
418
419 #ifdef GNULIB_GC_MD2
420   if (ctx->alg == GC_MD2)
421     {
422       md2_finish_ctx (&ctx->md2Context, ctx->hash);
423       digest = ctx->hash;
424     }
425   else
426 #endif
427     {
428       gcry_md_final (ctx->gch);
429       digest = gcry_md_read (ctx->gch, 0);
430     }
431
432   return digest;
433 }
434
435 void
436 gc_hash_close (gc_hash_handle handle)
437 {
438   _gc_hash_ctx *ctx = handle;
439
440 #ifdef GNULIB_GC_MD2
441   if (ctx->alg != GC_MD2)
442 #endif
443     gcry_md_close (ctx->gch);
444
445   free (ctx);
446 }
447
448 Gc_rc
449 gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf)
450 {
451   int gcryalg;
452
453   switch (hash)
454     {
455 #ifdef GNULIB_GC_MD2
456     case GC_MD2:
457       md2_buffer (in, inlen, resbuf);
458       return GC_OK;
459       break;
460 #endif
461
462 #ifdef GNULIB_GC_MD4
463     case GC_MD4:
464       gcryalg = GCRY_MD_MD4;
465       break;
466 #endif
467
468 #ifdef GNULIB_GC_MD5
469     case GC_MD5:
470       gcryalg = GCRY_MD_MD5;
471       break;
472 #endif
473
474 #ifdef GNULIB_GC_SHA1
475     case GC_SHA1:
476       gcryalg = GCRY_MD_SHA1;
477       break;
478 #endif
479
480 #ifdef GNULIB_GC_SHA256
481     case GC_SHA256:
482       gcryalg = GCRY_MD_SHA256;
483       break;
484 #endif
485
486 #ifdef GNULIB_GC_SHA384
487     case GC_SHA384:
488       gcryalg = GCRY_MD_SHA384;
489       break;
490 #endif
491
492 #ifdef GNULIB_GC_SHA512
493     case GC_SHA512:
494       gcryalg = GCRY_MD_SHA512;
495       break;
496 #endif
497
498 #ifdef GNULIB_GC_RMD160
499     case GC_RMD160:
500       gcryalg = GCRY_MD_RMD160;
501       break;
502 #endif
503
504     default:
505       return GC_INVALID_HASH;
506     }
507
508   gcry_md_hash_buffer (gcryalg, resbuf, in, inlen);
509
510   return GC_OK;
511 }
512
513 /* One-call interface. */
514
515 #ifdef GNULIB_GC_MD2
516 Gc_rc
517 gc_md2 (const void *in, size_t inlen, void *resbuf)
518 {
519   md2_buffer (in, inlen, resbuf);
520   return GC_OK;
521 }
522 #endif
523
524 #ifdef GNULIB_GC_MD4
525 Gc_rc
526 gc_md4 (const void *in, size_t inlen, void *resbuf)
527 {
528   size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_MD4);
529   gcry_md_hd_t hd;
530   gpg_error_t err;
531   unsigned char *p;
532
533   assert (outlen == GC_MD4_DIGEST_SIZE);
534
535   err = gcry_md_open (&hd, GCRY_MD_MD4, 0);
536   if (err != GPG_ERR_NO_ERROR)
537     return GC_INVALID_HASH;
538
539   gcry_md_write (hd, in, inlen);
540
541   p = gcry_md_read (hd, GCRY_MD_MD4);
542   if (p == NULL)
543     {
544       gcry_md_close (hd);
545       return GC_INVALID_HASH;
546     }
547
548   memcpy (resbuf, p, outlen);
549
550   gcry_md_close (hd);
551
552   return GC_OK;
553 }
554 #endif
555
556 #ifdef GNULIB_GC_MD5
557 Gc_rc
558 gc_md5 (const void *in, size_t inlen, void *resbuf)
559 {
560   size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_MD5);
561   gcry_md_hd_t hd;
562   gpg_error_t err;
563   unsigned char *p;
564
565   assert (outlen == GC_MD5_DIGEST_SIZE);
566
567   err = gcry_md_open (&hd, GCRY_MD_MD5, 0);
568   if (err != GPG_ERR_NO_ERROR)
569     return GC_INVALID_HASH;
570
571   gcry_md_write (hd, in, inlen);
572
573   p = gcry_md_read (hd, GCRY_MD_MD5);
574   if (p == NULL)
575     {
576       gcry_md_close (hd);
577       return GC_INVALID_HASH;
578     }
579
580   memcpy (resbuf, p, outlen);
581
582   gcry_md_close (hd);
583
584   return GC_OK;
585 }
586 #endif
587
588 #ifdef GNULIB_GC_SHA1
589 Gc_rc
590 gc_sha1 (const void *in, size_t inlen, void *resbuf)
591 {
592   size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
593   gcry_md_hd_t hd;
594   gpg_error_t err;
595   unsigned char *p;
596
597   assert (outlen == GC_SHA1_DIGEST_SIZE);
598
599   err = gcry_md_open (&hd, GCRY_MD_SHA1, 0);
600   if (err != GPG_ERR_NO_ERROR)
601     return GC_INVALID_HASH;
602
603   gcry_md_write (hd, in, inlen);
604
605   p = gcry_md_read (hd, GCRY_MD_SHA1);
606   if (p == NULL)
607     {
608       gcry_md_close (hd);
609       return GC_INVALID_HASH;
610     }
611
612   memcpy (resbuf, p, outlen);
613
614   gcry_md_close (hd);
615
616   return GC_OK;
617 }
618 #endif
619
620 #ifdef GNULIB_GC_HMAC_MD5
621 Gc_rc
622 gc_hmac_md5 (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_MD5);
626   gcry_md_hd_t mdh;
627   unsigned char *hash;
628   gpg_error_t err;
629
630   assert (hlen == 16);
631
632   err = gcry_md_open (&mdh, GCRY_MD_MD5, 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_MD5);
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
659
660 #ifdef GNULIB_GC_HMAC_SHA1
661 Gc_rc
662 gc_hmac_sha1 (const void *key, size_t keylen,
663               const void *in, size_t inlen, char *resbuf)
664 {
665   size_t hlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
666   gcry_md_hd_t mdh;
667   unsigned char *hash;
668   gpg_error_t err;
669
670   assert (hlen == GC_SHA1_DIGEST_SIZE);
671
672   err = gcry_md_open (&mdh, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC);
673   if (err != GPG_ERR_NO_ERROR)
674     return GC_INVALID_HASH;
675
676   err = gcry_md_setkey (mdh, key, keylen);
677   if (err != GPG_ERR_NO_ERROR)
678     {
679       gcry_md_close (mdh);
680       return GC_INVALID_HASH;
681     }
682
683   gcry_md_write (mdh, in, inlen);
684
685   hash = gcry_md_read (mdh, GCRY_MD_SHA1);
686   if (hash == NULL)
687     {
688       gcry_md_close (mdh);
689       return GC_INVALID_HASH;
690     }
691
692   memcpy (resbuf, hash, hlen);
693
694   gcry_md_close (mdh);
695
696   return GC_OK;
697 }
698 #endif