1 /* gc-libgcrypt.c --- Crypto wrappers around Libgcrypt for GC.
2 * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 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. */
31 /* Get libgcrypt API. */
46 err
= gcry_control (GCRYCTL_ANY_INITIALIZATION_P
);
47 if (err
== GPG_ERR_NO_ERROR
)
49 if (gcry_check_version (GCRYPT_VERSION
) == NULL
)
52 err
= gcry_control (GCRYCTL_INITIALIZATION_FINISHED
, NULL
, 0);
53 if (err
!= GPG_ERR_NO_ERROR
)
66 #ifdef GNULIB_GC_RANDOM
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
);
93 /* Memory allocation. */
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
)
101 gcry_set_allocation_handler (func_malloc
, secure_malloc
, secure_check
,
102 func_realloc
, func_free
);
108 gc_cipher_open (Gc_cipher alg
, Gc_cipher_mode mode
,
109 gc_cipher_handle
* outhandle
)
111 int gcryalg
, gcrymode
;
117 gcryalg
= GCRY_CIPHER_RIJNDAEL
;
121 gcryalg
= GCRY_CIPHER_RIJNDAEL
;
125 gcryalg
= GCRY_CIPHER_RIJNDAEL256
;
129 gcryalg
= GCRY_CIPHER_3DES
;
133 gcryalg
= GCRY_CIPHER_DES
;
138 gcryalg
= GCRY_CIPHER_ARCFOUR
;
142 gcryalg
= GCRY_CIPHER_RFC2268_40
;
146 return GC_INVALID_CIPHER
;
152 gcrymode
= GCRY_CIPHER_MODE_ECB
;
156 gcrymode
= GCRY_CIPHER_MODE_CBC
;
160 gcrymode
= GCRY_CIPHER_MODE_STREAM
;
164 return GC_INVALID_CIPHER
;
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
;
176 gc_cipher_setkey (gc_cipher_handle handle
, size_t keylen
, const char *key
)
180 err
= gcry_cipher_setkey ((gcry_cipher_hd_t
) handle
, key
, keylen
);
181 if (gcry_err_code (err
))
182 return GC_INVALID_CIPHER
;
188 gc_cipher_setiv (gc_cipher_handle handle
, size_t ivlen
, const char *iv
)
192 err
= gcry_cipher_setiv ((gcry_cipher_hd_t
) handle
, iv
, ivlen
);
193 if (gcry_err_code (err
))
194 return GC_INVALID_CIPHER
;
200 gc_cipher_encrypt_inline (gc_cipher_handle handle
, size_t len
, char *data
)
202 if (gcry_cipher_encrypt ((gcry_cipher_hd_t
) handle
,
203 data
, len
, NULL
, len
) != 0)
204 return GC_INVALID_CIPHER
;
210 gc_cipher_decrypt_inline (gc_cipher_handle handle
, size_t len
, char *data
)
212 if (gcry_cipher_decrypt ((gcry_cipher_hd_t
) handle
,
213 data
, len
, NULL
, len
) != 0)
214 return GC_INVALID_CIPHER
;
220 gc_cipher_close (gc_cipher_handle handle
)
222 gcry_cipher_close (handle
);
229 typedef struct _gc_hash_ctx
{
234 char hash
[GC_MD2_DIGEST_SIZE
];
235 struct md2_ctx md2Context
;
240 gc_hash_open (Gc_hash hash
, Gc_hash_mode mode
, gc_hash_handle
* outhandle
)
243 int gcryalg
, gcrymode
;
247 ctx
= calloc (sizeof (*ctx
), 1);
249 return GC_MALLOC_ERROR
;
257 gcryalg
= GCRY_MD_NONE
;
261 gcryalg
= GCRY_MD_MD4
;
265 gcryalg
= GCRY_MD_MD5
;
269 gcryalg
= GCRY_MD_SHA1
;
273 gcryalg
= GCRY_MD_RMD160
;
277 rc
= GC_INVALID_HASH
;
287 gcrymode
= GCRY_MD_FLAG_HMAC
;
291 rc
= GC_INVALID_HASH
;
294 if (rc
== GC_OK
&& gcryalg
!= GCRY_MD_NONE
)
296 err
= gcry_md_open (&ctx
->gch
, gcryalg
, gcrymode
);
297 if (gcry_err_code (err
))
298 rc
= GC_INVALID_HASH
;
310 gc_hash_clone (gc_hash_handle handle
, gc_hash_handle
* outhandle
)
312 _gc_hash_ctx
*in
= handle
;
316 *outhandle
= out
= calloc (sizeof (*out
), 1);
318 return GC_MALLOC_ERROR
;
320 memcpy (out
, in
, sizeof (*out
));
322 err
= gcry_md_copy (&out
->gch
, in
->gch
);
326 return GC_INVALID_HASH
;
333 gc_hash_digest_length (Gc_hash hash
)
340 len
= GC_MD2_DIGEST_SIZE
;
344 len
= GC_MD4_DIGEST_SIZE
;
348 len
= GC_MD5_DIGEST_SIZE
;
352 len
= GC_RMD160_DIGEST_SIZE
;
356 len
= GC_SHA1_DIGEST_SIZE
;
367 gc_hash_hmac_setkey (gc_hash_handle handle
, size_t len
, const char *key
)
369 _gc_hash_ctx
*ctx
= handle
;
371 if (ctx
->alg
!= GC_MD2
)
373 gcry_md_setkey (ctx
->gch
, key
, len
);
377 gc_hash_write (gc_hash_handle handle
, size_t len
, const char *data
)
379 _gc_hash_ctx
*ctx
= handle
;
382 if (ctx
->alg
== GC_MD2
)
383 md2_process_bytes (data
, len
, &ctx
->md2Context
);
386 gcry_md_write (ctx
->gch
, data
, len
);
390 gc_hash_read (gc_hash_handle handle
)
392 _gc_hash_ctx
*ctx
= handle
;
396 if (ctx
->alg
== GC_MD2
)
398 md2_finish_ctx (&ctx
->md2Context
, ctx
->hash
);
404 gcry_md_final (ctx
->gch
);
405 digest
= gcry_md_read (ctx
->gch
, 0);
412 gc_hash_close (gc_hash_handle handle
)
414 _gc_hash_ctx
*ctx
= handle
;
417 if (ctx
->alg
!= GC_MD2
)
419 gcry_md_close (ctx
->gch
);
425 gc_hash_buffer (Gc_hash hash
, const void *in
, size_t inlen
, char *resbuf
)
433 md2_buffer (in
, inlen
, resbuf
);
440 gcryalg
= GCRY_MD_MD4
;
446 gcryalg
= GCRY_MD_MD5
;
450 #ifdef GNULIB_GC_SHA1
452 gcryalg
= GCRY_MD_SHA1
;
456 #ifdef GNULIB_GC_RMD160
458 gcryalg
= GCRY_MD_RMD160
;
463 return GC_INVALID_HASH
;
466 gcry_md_hash_buffer (gcryalg
, resbuf
, in
, inlen
);
471 /* One-call interface. */
475 gc_md2 (const void *in
, size_t inlen
, void *resbuf
)
477 md2_buffer (in
, inlen
, resbuf
);
484 gc_md4 (const void *in
, size_t inlen
, void *resbuf
)
486 size_t outlen
= gcry_md_get_algo_dlen (GCRY_MD_MD4
);
491 assert (outlen
== GC_MD4_DIGEST_SIZE
);
493 err
= gcry_md_open (&hd
, GCRY_MD_MD4
, 0);
494 if (err
!= GPG_ERR_NO_ERROR
)
495 return GC_INVALID_HASH
;
497 gcry_md_write (hd
, in
, inlen
);
499 p
= gcry_md_read (hd
, GCRY_MD_MD4
);
503 return GC_INVALID_HASH
;
506 memcpy (resbuf
, p
, outlen
);
516 gc_md5 (const void *in
, size_t inlen
, void *resbuf
)
518 size_t outlen
= gcry_md_get_algo_dlen (GCRY_MD_MD5
);
523 assert (outlen
== GC_MD5_DIGEST_SIZE
);
525 err
= gcry_md_open (&hd
, GCRY_MD_MD5
, 0);
526 if (err
!= GPG_ERR_NO_ERROR
)
527 return GC_INVALID_HASH
;
529 gcry_md_write (hd
, in
, inlen
);
531 p
= gcry_md_read (hd
, GCRY_MD_MD5
);
535 return GC_INVALID_HASH
;
538 memcpy (resbuf
, p
, outlen
);
546 #ifdef GNULIB_GC_SHA1
548 gc_sha1 (const void *in
, size_t inlen
, void *resbuf
)
550 size_t outlen
= gcry_md_get_algo_dlen (GCRY_MD_SHA1
);
555 assert (outlen
== GC_SHA1_DIGEST_SIZE
);
557 err
= gcry_md_open (&hd
, GCRY_MD_SHA1
, 0);
558 if (err
!= GPG_ERR_NO_ERROR
)
559 return GC_INVALID_HASH
;
561 gcry_md_write (hd
, in
, inlen
);
563 p
= gcry_md_read (hd
, GCRY_MD_SHA1
);
567 return GC_INVALID_HASH
;
570 memcpy (resbuf
, p
, outlen
);
578 #ifdef GNULIB_GC_HMAC_MD5
580 gc_hmac_md5 (const void *key
, size_t keylen
,
581 const void *in
, size_t inlen
, char *resbuf
)
583 size_t hlen
= gcry_md_get_algo_dlen (GCRY_MD_MD5
);
590 err
= gcry_md_open (&mdh
, GCRY_MD_MD5
, GCRY_MD_FLAG_HMAC
);
591 if (err
!= GPG_ERR_NO_ERROR
)
592 return GC_INVALID_HASH
;
594 err
= gcry_md_setkey (mdh
, key
, keylen
);
595 if (err
!= GPG_ERR_NO_ERROR
)
598 return GC_INVALID_HASH
;
601 gcry_md_write (mdh
, in
, inlen
);
603 hash
= gcry_md_read (mdh
, GCRY_MD_MD5
);
607 return GC_INVALID_HASH
;
610 memcpy (resbuf
, hash
, hlen
);
618 #ifdef GNULIB_GC_HMAC_SHA1
620 gc_hmac_sha1 (const void *key
, size_t keylen
,
621 const void *in
, size_t inlen
, char *resbuf
)
623 size_t hlen
= gcry_md_get_algo_dlen (GCRY_MD_SHA1
);
628 assert (hlen
== GC_SHA1_DIGEST_SIZE
);
630 err
= gcry_md_open (&mdh
, GCRY_MD_SHA1
, GCRY_MD_FLAG_HMAC
);
631 if (err
!= GPG_ERR_NO_ERROR
)
632 return GC_INVALID_HASH
;
634 err
= gcry_md_setkey (mdh
, key
, keylen
);
635 if (err
!= GPG_ERR_NO_ERROR
)
638 return GC_INVALID_HASH
;
641 gcry_md_write (mdh
, in
, inlen
);
643 hash
= gcry_md_read (mdh
, GCRY_MD_SHA1
);
647 return GC_INVALID_HASH
;
650 memcpy (resbuf
, hash
, hlen
);