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