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. */
33 /* Get libgcrypt API. */
48 err = gcry_control (GCRYCTL_ANY_INITIALIZATION_P);
49 if (err == GPG_ERR_NO_ERROR)
51 if (gcry_check_version (GCRYPT_VERSION) == NULL)
54 err = gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL, 0);
55 if (err != GPG_ERR_NO_ERROR)
71 gc_nonce (char *data, size_t datalen)
73 gcry_create_nonce ((unsigned char *) data, datalen);
78 gc_pseudo_random (char *data, size_t datalen)
80 gcry_randomize ((unsigned char *) data, datalen, GCRY_STRONG_RANDOM);
85 gc_random (char *data, size_t datalen)
87 gcry_randomize ((unsigned char *) data, datalen, GCRY_VERY_STRONG_RANDOM);
91 /* Memory allocation. */
94 gc_set_allocators (gc_malloc_t func_malloc,
95 gc_malloc_t secure_malloc,
96 gc_secure_check_t secure_check,
97 gc_realloc_t func_realloc, gc_free_t func_free)
99 gcry_set_allocation_handler (func_malloc, secure_malloc, secure_check,
100 func_realloc, func_free);
106 gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode,
107 gc_cipher_handle * outhandle)
109 int gcryalg, gcrymode;
115 gcryalg = GCRY_CIPHER_RIJNDAEL;
119 gcryalg = GCRY_CIPHER_RIJNDAEL;
123 gcryalg = GCRY_CIPHER_RIJNDAEL256;
127 gcryalg = GCRY_CIPHER_3DES;
131 gcryalg = GCRY_CIPHER_DES;
136 gcryalg = GCRY_CIPHER_ARCFOUR;
140 gcryalg = GCRY_CIPHER_RFC2268_40;
144 return GC_INVALID_CIPHER;
150 gcrymode = GCRY_CIPHER_MODE_ECB;
154 gcrymode = GCRY_CIPHER_MODE_CBC;
158 gcrymode = GCRY_CIPHER_MODE_STREAM;
162 return GC_INVALID_CIPHER;
165 err = gcry_cipher_open ((gcry_cipher_hd_t *) outhandle,
166 gcryalg, gcrymode, 0);
167 if (gcry_err_code (err))
168 return GC_INVALID_CIPHER;
174 gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key)
178 err = gcry_cipher_setkey ((gcry_cipher_hd_t) handle, key, keylen);
179 if (gcry_err_code (err))
180 return GC_INVALID_CIPHER;
186 gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv)
190 err = gcry_cipher_setiv ((gcry_cipher_hd_t) handle, iv, ivlen);
191 if (gcry_err_code (err))
192 return GC_INVALID_CIPHER;
198 gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data)
200 if (gcry_cipher_encrypt ((gcry_cipher_hd_t) handle,
201 data, len, NULL, len) != 0)
202 return GC_INVALID_CIPHER;
208 gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data)
210 if (gcry_cipher_decrypt ((gcry_cipher_hd_t) handle,
211 data, len, NULL, len) != 0)
212 return GC_INVALID_CIPHER;
218 gc_cipher_close (gc_cipher_handle handle)
220 gcry_cipher_close (handle);
227 typedef struct _gc_hash_ctx {
232 char hash[GC_MD2_DIGEST_SIZE];
233 struct md2_ctx md2Context;
238 gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle)
241 int gcryalg, gcrymode;
245 ctx = calloc (sizeof (*ctx), 1);
247 return GC_MALLOC_ERROR;
255 gcryalg = GCRY_MD_NONE;
259 gcryalg = GCRY_MD_MD4;
263 gcryalg = GCRY_MD_MD5;
267 gcryalg = GCRY_MD_SHA1;
271 gcryalg = GCRY_MD_RMD160;
275 rc = GC_INVALID_HASH;
285 gcrymode = GCRY_MD_FLAG_HMAC;
289 rc = GC_INVALID_HASH;
292 if (rc == GC_OK && gcryalg != GCRY_MD_NONE)
294 err = gcry_md_open (&ctx->gch, gcryalg, gcrymode);
295 if (gcry_err_code (err))
296 rc = GC_INVALID_HASH;
308 gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle)
310 _gc_hash_ctx *in = handle;
314 *outhandle = out = calloc (sizeof (*out), 1);
316 return GC_MALLOC_ERROR;
318 memcpy (out, in, sizeof (*out));
320 err = gcry_md_copy (&out->gch, in->gch);
324 return GC_INVALID_HASH;
331 gc_hash_digest_length (Gc_hash hash)
338 len = GC_MD2_DIGEST_SIZE;
342 len = GC_MD4_DIGEST_SIZE;
346 len = GC_MD5_DIGEST_SIZE;
350 len = GC_RMD160_DIGEST_SIZE;
354 len = GC_SHA1_DIGEST_SIZE;
365 gc_hash_hmac_setkey (gc_hash_handle handle, size_t len, const char *key)
367 _gc_hash_ctx *ctx = handle;
369 if (ctx->alg != GC_MD2)
371 gcry_md_setkey (ctx->gch, key, len);
375 gc_hash_write (gc_hash_handle handle, size_t len, const char *data)
377 _gc_hash_ctx *ctx = handle;
380 if (ctx->alg == GC_MD2)
381 md2_process_bytes (data, len, &ctx->md2Context);
384 gcry_md_write (ctx->gch, data, len);
388 gc_hash_read (gc_hash_handle handle)
390 _gc_hash_ctx *ctx = handle;
394 if (ctx->alg == GC_MD2)
396 md2_finish_ctx (&ctx->md2Context, ctx->hash);
402 gcry_md_final (ctx->gch);
403 digest = gcry_md_read (ctx->gch, 0);
410 gc_hash_close (gc_hash_handle handle)
412 _gc_hash_ctx *ctx = handle;
415 if (ctx->alg != GC_MD2)
417 gcry_md_close (ctx->gch);
423 gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf)
431 md2_buffer (in, inlen, resbuf);
438 gcryalg = GCRY_MD_MD4;
444 gcryalg = GCRY_MD_MD5;
450 gcryalg = GCRY_MD_SHA1;
456 gcryalg = GCRY_MD_RMD160;
461 return GC_INVALID_HASH;
464 gcry_md_hash_buffer (gcryalg, resbuf, in, inlen);
469 /* One-call interface. */
473 gc_md2 (const void *in, size_t inlen, void *resbuf)
475 md2_buffer (in, inlen, resbuf);
482 gc_md4 (const void *in, size_t inlen, void *resbuf)
484 size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_MD4);
489 assert (outlen == GC_MD4_DIGEST_SIZE);
491 err = gcry_md_open (&hd, GCRY_MD_MD4, 0);
492 if (err != GPG_ERR_NO_ERROR)
493 return GC_INVALID_HASH;
495 gcry_md_write (hd, in, inlen);
497 p = gcry_md_read (hd, GCRY_MD_MD4);
501 return GC_INVALID_HASH;
504 memcpy (resbuf, p, outlen);
514 gc_md5 (const void *in, size_t inlen, void *resbuf)
516 size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_MD5);
521 assert (outlen == GC_MD5_DIGEST_SIZE);
523 err = gcry_md_open (&hd, GCRY_MD_MD5, 0);
524 if (err != GPG_ERR_NO_ERROR)
525 return GC_INVALID_HASH;
527 gcry_md_write (hd, in, inlen);
529 p = gcry_md_read (hd, GCRY_MD_MD5);
533 return GC_INVALID_HASH;
536 memcpy (resbuf, p, outlen);
546 gc_sha1 (const void *in, size_t inlen, void *resbuf)
548 size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
553 assert (outlen == GC_SHA1_DIGEST_SIZE);
555 err = gcry_md_open (&hd, GCRY_MD_SHA1, 0);
556 if (err != GPG_ERR_NO_ERROR)
557 return GC_INVALID_HASH;
559 gcry_md_write (hd, in, inlen);
561 p = gcry_md_read (hd, GCRY_MD_SHA1);
565 return GC_INVALID_HASH;
568 memcpy (resbuf, p, outlen);
576 #ifdef GC_USE_HMAC_MD5
578 gc_hmac_md5 (const void *key, size_t keylen,
579 const void *in, size_t inlen, char *resbuf)
581 size_t hlen = gcry_md_get_algo_dlen (GCRY_MD_MD5);
588 err = gcry_md_open (&mdh, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC);
589 if (err != GPG_ERR_NO_ERROR)
590 return GC_INVALID_HASH;
592 err = gcry_md_setkey (mdh, key, keylen);
593 if (err != GPG_ERR_NO_ERROR)
596 return GC_INVALID_HASH;
599 gcry_md_write (mdh, in, inlen);
601 hash = gcry_md_read (mdh, GCRY_MD_MD5);
605 return GC_INVALID_HASH;
608 memcpy (resbuf, hash, hlen);
616 #ifdef GC_USE_HMAC_SHA1
618 gc_hmac_sha1 (const void *key, size_t keylen,
619 const void *in, size_t inlen, char *resbuf)
621 size_t hlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
626 assert (hlen == GC_SHA1_DIGEST_SIZE);
628 err = gcry_md_open (&mdh, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC);
629 if (err != GPG_ERR_NO_ERROR)
630 return GC_INVALID_HASH;
632 err = gcry_md_setkey (mdh, key, keylen);
633 if (err != GPG_ERR_NO_ERROR)
636 return GC_INVALID_HASH;
639 gcry_md_write (mdh, in, inlen);
641 hash = gcry_md_read (mdh, GCRY_MD_SHA1);
645 return GC_INVALID_HASH;
648 memcpy (resbuf, hash, hlen);