Add gc-md4 and gc-md4-tests modules.
[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_CBC:
144       gcrymode = GCRY_CIPHER_MODE_CBC;
145       break;
146
147     case GC_STREAM:
148       gcrymode = GCRY_CIPHER_MODE_STREAM;
149       break;
150
151     default:
152       return GC_INVALID_CIPHER;
153     }
154
155   err = gcry_cipher_open ((gcry_cipher_hd_t *) outhandle,
156                           gcryalg, gcrymode, 0);
157   if (gcry_err_code (err))
158     return GC_INVALID_CIPHER;
159
160   return GC_OK;
161 }
162
163 Gc_rc
164 gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key)
165 {
166   gcry_error_t err;
167
168   err = gcry_cipher_setkey ((gcry_cipher_hd_t) handle, key, keylen);
169   if (gcry_err_code (err))
170     return GC_INVALID_CIPHER;
171
172   return GC_OK;
173 }
174
175 Gc_rc
176 gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv)
177 {
178   gcry_error_t err;
179
180   err = gcry_cipher_setiv ((gcry_cipher_hd_t) handle, iv, ivlen);
181   if (gcry_err_code (err))
182     return GC_INVALID_CIPHER;
183
184   return GC_OK;
185 }
186
187 Gc_rc
188 gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data)
189 {
190   if (gcry_cipher_encrypt ((gcry_cipher_hd_t) handle,
191                            data, len, NULL, len) != 0)
192     return GC_INVALID_CIPHER;
193
194   return GC_OK;
195 }
196
197 Gc_rc
198 gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data)
199 {
200   if (gcry_cipher_decrypt ((gcry_cipher_hd_t) handle,
201                            data, len, NULL, len) != 0)
202     return GC_INVALID_CIPHER;
203
204   return GC_OK;
205 }
206
207 Gc_rc
208 gc_cipher_close (gc_cipher_handle handle)
209 {
210   gcry_cipher_close (handle);
211
212   return GC_OK;
213 }
214
215 /* Hashes. */
216
217 Gc_rc
218 gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle)
219 {
220   int gcryalg, gcrymode;
221   gcry_error_t err;
222
223   switch (hash)
224     {
225     case GC_MD4:
226       gcryalg = GCRY_MD_MD4;
227       break;
228
229     case GC_MD5:
230       gcryalg = GCRY_MD_MD5;
231       break;
232
233     case GC_SHA1:
234       gcryalg = GCRY_MD_SHA1;
235       break;
236
237     case GC_RMD160:
238       gcryalg = GCRY_MD_RMD160;
239       break;
240
241     default:
242       return GC_INVALID_HASH;
243     }
244
245   switch (mode)
246     {
247     case 0:
248       gcrymode = 0;
249       break;
250
251     case GC_HMAC:
252       gcrymode = GCRY_MD_FLAG_HMAC;
253       break;
254
255     default:
256       return GC_INVALID_HASH;
257     }
258
259   err = gcry_md_open ((gcry_md_hd_t *) outhandle, gcryalg, gcrymode);
260   if (gcry_err_code (err))
261     return GC_INVALID_HASH;
262
263   return GC_OK;
264 }
265
266 Gc_rc
267 gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle)
268 {
269   int err;
270
271   err = gcry_md_copy ((gcry_md_hd_t *) outhandle, (gcry_md_hd_t) handle);
272   if (err)
273     return GC_INVALID_HASH;
274
275   return GC_OK;
276 }
277
278 size_t
279 gc_hash_digest_length (Gc_hash hash)
280 {
281   int gcryalg;
282
283   switch (hash)
284     {
285     case GC_MD4:
286       gcryalg = GCRY_MD_MD4;
287       break;
288
289     case GC_MD5:
290       gcryalg = GCRY_MD_MD5;
291       break;
292
293     case GC_SHA1:
294       gcryalg = GCRY_MD_SHA1;
295       break;
296
297     case GC_RMD160:
298       gcryalg = GCRY_MD_RMD160;
299       break;
300
301     default:
302       return 0;
303     }
304
305   return gcry_md_get_algo_dlen (gcryalg);
306 }
307
308 void
309 gc_hash_hmac_setkey (gc_hash_handle handle, size_t len, const char *key)
310 {
311   gcry_md_setkey ((gcry_md_hd_t) handle, key, len);
312 }
313
314 void
315 gc_hash_write (gc_hash_handle handle, size_t len, const char *data)
316 {
317   gcry_md_write ((gcry_md_hd_t) handle, data, len);
318 }
319
320 const char *
321 gc_hash_read (gc_hash_handle handle)
322 {
323   const char *digest;
324
325   gcry_md_final ((gcry_md_hd_t) handle);
326   digest = gcry_md_read ((gcry_md_hd_t) handle, 0);
327
328   return digest;
329 }
330
331 void
332 gc_hash_close (gc_hash_handle handle)
333 {
334   gcry_md_close ((gcry_md_hd_t) handle);
335 }
336
337 Gc_rc
338 gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf)
339 {
340   int gcryalg;
341
342   switch (hash)
343     {
344 #ifdef GC_USE_MD4
345     case GC_MD4:
346       gcryalg = GCRY_MD_MD4;
347       break;
348 #endif
349
350 #ifdef GC_USE_MD5
351     case GC_MD5:
352       gcryalg = GCRY_MD_MD5;
353       break;
354 #endif
355
356 #ifdef GC_USE_SHA1
357     case GC_SHA1:
358       gcryalg = GCRY_MD_SHA1;
359       break;
360 #endif
361
362 #ifdef GC_USE_RMD160
363     case GC_RMD160:
364       gcryalg = GCRY_MD_RMD160;
365       break;
366 #endif
367
368     default:
369       return GC_INVALID_HASH;
370     }
371
372   gcry_md_hash_buffer (gcryalg, resbuf, in, inlen);
373
374   return GC_OK;
375 }
376
377 /* One-call interface. */
378
379 #ifdef GC_USE_MD4
380 Gc_rc
381 gc_md4 (const void *in, size_t inlen, void *resbuf)
382 {
383   size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_MD4);
384   gcry_md_hd_t hd;
385   gpg_error_t err;
386   unsigned char *p;
387
388   assert (outlen == GC_MD4_DIGEST_SIZE);
389
390   err = gcry_md_open (&hd, GCRY_MD_MD4, 0);
391   if (err != GPG_ERR_NO_ERROR)
392     return GC_INVALID_HASH;
393
394   gcry_md_write (hd, in, inlen);
395
396   p = gcry_md_read (hd, GCRY_MD_MD4);
397   if (p == NULL)
398     {
399       gcry_md_close (hd);
400       return GC_INVALID_HASH;
401     }
402
403   memcpy (resbuf, p, outlen);
404
405   gcry_md_close (hd);
406
407   return GC_OK;
408 }
409 #endif
410
411 #ifdef GC_USE_MD5
412 Gc_rc
413 gc_md5 (const void *in, size_t inlen, void *resbuf)
414 {
415   size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_MD5);
416   gcry_md_hd_t hd;
417   gpg_error_t err;
418   unsigned char *p;
419
420   assert (outlen == GC_MD5_DIGEST_SIZE);
421
422   err = gcry_md_open (&hd, GCRY_MD_MD5, 0);
423   if (err != GPG_ERR_NO_ERROR)
424     return GC_INVALID_HASH;
425
426   gcry_md_write (hd, in, inlen);
427
428   p = gcry_md_read (hd, GCRY_MD_MD5);
429   if (p == NULL)
430     {
431       gcry_md_close (hd);
432       return GC_INVALID_HASH;
433     }
434
435   memcpy (resbuf, p, outlen);
436
437   gcry_md_close (hd);
438
439   return GC_OK;
440 }
441 #endif
442
443 #ifdef GC_USE_SHA1
444 Gc_rc
445 gc_sha1 (const void *in, size_t inlen, void *resbuf)
446 {
447   size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
448   gcry_md_hd_t hd;
449   gpg_error_t err;
450   unsigned char *p;
451
452   assert (outlen == GC_SHA1_DIGEST_SIZE);
453
454   err = gcry_md_open (&hd, GCRY_MD_SHA1, 0);
455   if (err != GPG_ERR_NO_ERROR)
456     return GC_INVALID_HASH;
457
458   gcry_md_write (hd, in, inlen);
459
460   p = gcry_md_read (hd, GCRY_MD_SHA1);
461   if (p == NULL)
462     {
463       gcry_md_close (hd);
464       return GC_INVALID_HASH;
465     }
466
467   memcpy (resbuf, p, outlen);
468
469   gcry_md_close (hd);
470
471   return GC_OK;
472 }
473 #endif
474
475 #ifdef GC_USE_HMAC_MD5
476 Gc_rc
477 gc_hmac_md5 (const void *key, size_t keylen,
478              const void *in, size_t inlen, char *resbuf)
479 {
480   size_t hlen = gcry_md_get_algo_dlen (GCRY_MD_MD5);
481   gcry_md_hd_t mdh;
482   unsigned char *hash;
483   gpg_error_t err;
484
485   assert (hlen == 16);
486
487   err = gcry_md_open (&mdh, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC);
488   if (err != GPG_ERR_NO_ERROR)
489     return GC_INVALID_HASH;
490
491   err = gcry_md_setkey (mdh, key, keylen);
492   if (err != GPG_ERR_NO_ERROR)
493     {
494       gcry_md_close (mdh);
495       return GC_INVALID_HASH;
496     }
497
498   gcry_md_write (mdh, in, inlen);
499
500   hash = gcry_md_read (mdh, GCRY_MD_MD5);
501   if (hash == NULL)
502     {
503       gcry_md_close (mdh);
504       return GC_INVALID_HASH;
505     }
506
507   memcpy (resbuf, hash, hlen);
508
509   gcry_md_close (mdh);
510
511   return GC_OK;
512 }
513 #endif
514
515 #ifdef GC_USE_HMAC_SHA1
516 Gc_rc
517 gc_hmac_sha1 (const void *key, size_t keylen,
518               const void *in, size_t inlen, char *resbuf)
519 {
520   size_t hlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
521   gcry_md_hd_t mdh;
522   unsigned char *hash;
523   gpg_error_t err;
524
525   assert (hlen == GC_SHA1_DIGEST_SIZE);
526
527   err = gcry_md_open (&mdh, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC);
528   if (err != GPG_ERR_NO_ERROR)
529     return GC_INVALID_HASH;
530
531   err = gcry_md_setkey (mdh, key, keylen);
532   if (err != GPG_ERR_NO_ERROR)
533     {
534       gcry_md_close (mdh);
535       return GC_INVALID_HASH;
536     }
537
538   gcry_md_write (mdh, in, inlen);
539
540   hash = gcry_md_read (mdh, GCRY_MD_SHA1);
541   if (hash == NULL)
542     {
543       gcry_md_close (mdh);
544       return GC_INVALID_HASH;
545     }
546
547   memcpy (resbuf, hash, hlen);
548
549   gcry_md_close (mdh);
550
551   return GC_OK;
552 }
553 #endif