1 /* gc-libgcrypt.c --- Crypto wrappers around Libgcrypt for GC.
2 * Copyright (C) 2002, 2003, 2004, 2005 Simon Josefsson
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.
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.
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
21 /* Note: This file is only built if GC uses Libgcrypt. */
30 /* Get libgcrypt API. */
42 err = gcry_control (GCRYCTL_ANY_INITIALIZATION_P);
43 if (err == GPG_ERR_NO_ERROR)
45 if (gcry_check_version (GCRYPT_VERSION) == NULL)
48 err = gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL, 0);
49 if (err != GPG_ERR_NO_ERROR)
65 gc_nonce (char *data, size_t datalen)
67 gcry_create_nonce ((unsigned char *) data, datalen);
72 gc_pseudo_random (char *data, size_t datalen)
74 gcry_randomize ((unsigned char *) data, datalen, GCRY_STRONG_RANDOM);
79 gc_random (char *data, size_t datalen)
81 gcry_randomize ((unsigned char *) data, datalen, GCRY_VERY_STRONG_RANDOM);
85 /* Memory allocation. */
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)
93 gcry_set_allocation_handler (func_malloc, secure_malloc, secure_check,
94 func_realloc, func_free);
100 gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode,
101 gc_cipher_handle * outhandle)
103 int gcryalg, gcrymode;
109 gcryalg = GCRY_CIPHER_RIJNDAEL;
113 gcryalg = GCRY_CIPHER_RIJNDAEL;
117 gcryalg = GCRY_CIPHER_RIJNDAEL256;
121 gcryalg = GCRY_CIPHER_3DES;
125 gcryalg = GCRY_CIPHER_DES;
130 gcryalg = GCRY_CIPHER_ARCFOUR;
134 gcryalg = GCRY_CIPHER_RFC2268_40;
138 return GC_INVALID_CIPHER;
144 gcrymode = GCRY_CIPHER_MODE_ECB;
148 gcrymode = GCRY_CIPHER_MODE_CBC;
152 gcrymode = GCRY_CIPHER_MODE_STREAM;
156 return GC_INVALID_CIPHER;
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;
168 gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key)
172 err = gcry_cipher_setkey ((gcry_cipher_hd_t) handle, key, keylen);
173 if (gcry_err_code (err))
174 return GC_INVALID_CIPHER;
180 gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv)
184 err = gcry_cipher_setiv ((gcry_cipher_hd_t) handle, iv, ivlen);
185 if (gcry_err_code (err))
186 return GC_INVALID_CIPHER;
192 gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data)
194 if (gcry_cipher_encrypt ((gcry_cipher_hd_t) handle,
195 data, len, NULL, len) != 0)
196 return GC_INVALID_CIPHER;
202 gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data)
204 if (gcry_cipher_decrypt ((gcry_cipher_hd_t) handle,
205 data, len, NULL, len) != 0)
206 return GC_INVALID_CIPHER;
212 gc_cipher_close (gc_cipher_handle handle)
214 gcry_cipher_close (handle);
222 gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle)
224 int gcryalg, gcrymode;
230 gcryalg = GCRY_MD_MD4;
234 gcryalg = GCRY_MD_MD5;
238 gcryalg = GCRY_MD_SHA1;
242 gcryalg = GCRY_MD_RMD160;
246 return GC_INVALID_HASH;
256 gcrymode = GCRY_MD_FLAG_HMAC;
260 return GC_INVALID_HASH;
263 err = gcry_md_open ((gcry_md_hd_t *) outhandle, gcryalg, gcrymode);
264 if (gcry_err_code (err))
265 return GC_INVALID_HASH;
271 gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle)
275 err = gcry_md_copy ((gcry_md_hd_t *) outhandle, (gcry_md_hd_t) handle);
277 return GC_INVALID_HASH;
283 gc_hash_digest_length (Gc_hash hash)
290 gcryalg = GCRY_MD_MD4;
294 gcryalg = GCRY_MD_MD5;
298 gcryalg = GCRY_MD_SHA1;
302 gcryalg = GCRY_MD_RMD160;
309 return gcry_md_get_algo_dlen (gcryalg);
313 gc_hash_hmac_setkey (gc_hash_handle handle, size_t len, const char *key)
315 gcry_md_setkey ((gcry_md_hd_t) handle, key, len);
319 gc_hash_write (gc_hash_handle handle, size_t len, const char *data)
321 gcry_md_write ((gcry_md_hd_t) handle, data, len);
325 gc_hash_read (gc_hash_handle handle)
329 gcry_md_final ((gcry_md_hd_t) handle);
330 digest = gcry_md_read ((gcry_md_hd_t) handle, 0);
336 gc_hash_close (gc_hash_handle handle)
338 gcry_md_close ((gcry_md_hd_t) handle);
342 gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf)
350 gcryalg = GCRY_MD_MD4;
356 gcryalg = GCRY_MD_MD5;
362 gcryalg = GCRY_MD_SHA1;
368 gcryalg = GCRY_MD_RMD160;
373 return GC_INVALID_HASH;
376 gcry_md_hash_buffer (gcryalg, resbuf, in, inlen);
381 /* One-call interface. */
385 gc_md4 (const void *in, size_t inlen, void *resbuf)
387 size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_MD4);
392 assert (outlen == GC_MD4_DIGEST_SIZE);
394 err = gcry_md_open (&hd, GCRY_MD_MD4, 0);
395 if (err != GPG_ERR_NO_ERROR)
396 return GC_INVALID_HASH;
398 gcry_md_write (hd, in, inlen);
400 p = gcry_md_read (hd, GCRY_MD_MD4);
404 return GC_INVALID_HASH;
407 memcpy (resbuf, p, outlen);
417 gc_md5 (const void *in, size_t inlen, void *resbuf)
419 size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_MD5);
424 assert (outlen == GC_MD5_DIGEST_SIZE);
426 err = gcry_md_open (&hd, GCRY_MD_MD5, 0);
427 if (err != GPG_ERR_NO_ERROR)
428 return GC_INVALID_HASH;
430 gcry_md_write (hd, in, inlen);
432 p = gcry_md_read (hd, GCRY_MD_MD5);
436 return GC_INVALID_HASH;
439 memcpy (resbuf, p, outlen);
449 gc_sha1 (const void *in, size_t inlen, void *resbuf)
451 size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
456 assert (outlen == GC_SHA1_DIGEST_SIZE);
458 err = gcry_md_open (&hd, GCRY_MD_SHA1, 0);
459 if (err != GPG_ERR_NO_ERROR)
460 return GC_INVALID_HASH;
462 gcry_md_write (hd, in, inlen);
464 p = gcry_md_read (hd, GCRY_MD_SHA1);
468 return GC_INVALID_HASH;
471 memcpy (resbuf, p, outlen);
479 #ifdef GC_USE_HMAC_MD5
481 gc_hmac_md5 (const void *key, size_t keylen,
482 const void *in, size_t inlen, char *resbuf)
484 size_t hlen = gcry_md_get_algo_dlen (GCRY_MD_MD5);
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;
495 err = gcry_md_setkey (mdh, key, keylen);
496 if (err != GPG_ERR_NO_ERROR)
499 return GC_INVALID_HASH;
502 gcry_md_write (mdh, in, inlen);
504 hash = gcry_md_read (mdh, GCRY_MD_MD5);
508 return GC_INVALID_HASH;
511 memcpy (resbuf, hash, hlen);
519 #ifdef GC_USE_HMAC_SHA1
521 gc_hmac_sha1 (const void *key, size_t keylen,
522 const void *in, size_t inlen, char *resbuf)
524 size_t hlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
529 assert (hlen == GC_SHA1_DIGEST_SIZE);
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;
535 err = gcry_md_setkey (mdh, key, keylen);
536 if (err != GPG_ERR_NO_ERROR)
539 return GC_INVALID_HASH;
542 gcry_md_write (mdh, in, inlen);
544 hash = gcry_md_read (mdh, GCRY_MD_SHA1);
548 return GC_INVALID_HASH;
551 memcpy (resbuf, hash, hlen);