1 /* gc-libgcrypt.c --- Crypto wrappers around Libgcrypt for GC.
2 * Copyright (C) 2002-2018 Free Software Foundation, Inc.
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, see <https://www.gnu.org/licenses/>.
19 /* Note: This file is only built if GC uses Libgcrypt. */
29 /* Get libgcrypt API. */
37 #ifndef MIN_GCRYPT_VERSION
38 # define MIN_GCRYPT_VERSION "1.4.4"
48 err
= gcry_control (GCRYCTL_ANY_INITIALIZATION_P
);
49 if (err
== GPG_ERR_NO_ERROR
)
51 if (gcry_control (GCRYCTL_DISABLE_SECMEM
, NULL
, 0))
54 if (gcry_check_version (MIN_GCRYPT_VERSION
) == NULL
)
57 err
= gcry_control (GCRYCTL_INITIALIZATION_FINISHED
, NULL
, 0);
58 if (err
!= GPG_ERR_NO_ERROR
)
71 #ifdef GNULIB_GC_RANDOM
76 gc_nonce (char *data
, size_t datalen
)
78 gcry_create_nonce ((unsigned char *) data
, datalen
);
83 gc_pseudo_random (char *data
, size_t datalen
)
85 gcry_randomize ((unsigned char *) data
, datalen
, GCRY_STRONG_RANDOM
);
90 gc_random (char *data
, size_t datalen
)
92 gcry_randomize ((unsigned char *) data
, datalen
, GCRY_VERY_STRONG_RANDOM
);
98 /* Memory allocation. */
101 gc_set_allocators (gc_malloc_t func_malloc
,
102 gc_malloc_t secure_malloc
,
103 gc_secure_check_t secure_check
,
104 gc_realloc_t func_realloc
, gc_free_t func_free
)
106 gcry_set_allocation_handler (func_malloc
, secure_malloc
, secure_check
,
107 func_realloc
, func_free
);
113 gc_cipher_open (Gc_cipher alg
, Gc_cipher_mode mode
,
114 gc_cipher_handle
* outhandle
)
116 int gcryalg
, gcrymode
;
122 gcryalg
= GCRY_CIPHER_RIJNDAEL
;
126 gcryalg
= GCRY_CIPHER_RIJNDAEL
;
130 gcryalg
= GCRY_CIPHER_RIJNDAEL256
;
134 gcryalg
= GCRY_CIPHER_3DES
;
138 gcryalg
= GCRY_CIPHER_DES
;
143 gcryalg
= GCRY_CIPHER_ARCFOUR
;
147 gcryalg
= GCRY_CIPHER_RFC2268_40
;
152 gcryalg
= GCRY_CIPHER_CAMELLIA128
;
156 gcryalg
= GCRY_CIPHER_CAMELLIA256
;
161 return GC_INVALID_CIPHER
;
167 gcrymode
= GCRY_CIPHER_MODE_ECB
;
171 gcrymode
= GCRY_CIPHER_MODE_CBC
;
175 gcrymode
= GCRY_CIPHER_MODE_STREAM
;
179 return GC_INVALID_CIPHER
;
182 err
= gcry_cipher_open ((gcry_cipher_hd_t
*) outhandle
,
183 gcryalg
, gcrymode
, 0);
184 if (gcry_err_code (err
))
185 return GC_INVALID_CIPHER
;
191 gc_cipher_setkey (gc_cipher_handle handle
, size_t keylen
, const char *key
)
195 err
= gcry_cipher_setkey ((gcry_cipher_hd_t
) handle
, key
, keylen
);
196 if (gcry_err_code (err
))
197 return GC_INVALID_CIPHER
;
203 gc_cipher_setiv (gc_cipher_handle handle
, size_t ivlen
, const char *iv
)
207 err
= gcry_cipher_setiv ((gcry_cipher_hd_t
) handle
, iv
, ivlen
);
208 if (gcry_err_code (err
))
209 return GC_INVALID_CIPHER
;
215 gc_cipher_encrypt_inline (gc_cipher_handle handle
, size_t len
, char *data
)
217 if (gcry_cipher_encrypt ((gcry_cipher_hd_t
) handle
,
218 data
, len
, NULL
, len
) != 0)
219 return GC_INVALID_CIPHER
;
225 gc_cipher_decrypt_inline (gc_cipher_handle handle
, size_t len
, char *data
)
227 if (gcry_cipher_decrypt ((gcry_cipher_hd_t
) handle
,
228 data
, len
, NULL
, len
) != 0)
229 return GC_INVALID_CIPHER
;
235 gc_cipher_close (gc_cipher_handle handle
)
237 gcry_cipher_close (handle
);
244 typedef struct _gc_hash_ctx
{
249 char hash
[GC_MD2_DIGEST_SIZE
];
250 struct md2_ctx md2Context
;
255 gc_hash_open (Gc_hash hash
, Gc_hash_mode mode
, gc_hash_handle
* outhandle
)
258 int gcryalg
= 0, gcrymode
= 0;
262 ctx
= calloc (sizeof (*ctx
), 1);
264 return GC_MALLOC_ERROR
;
272 gcryalg
= GCRY_MD_NONE
;
276 gcryalg
= GCRY_MD_MD4
;
280 gcryalg
= GCRY_MD_MD5
;
284 gcryalg
= GCRY_MD_SHA1
;
288 gcryalg
= GCRY_MD_SHA256
;
292 gcryalg
= GCRY_MD_SHA384
;
296 gcryalg
= GCRY_MD_SHA512
;
300 gcryalg
= GCRY_MD_SHA224
;
304 gcryalg
= GCRY_MD_RMD160
;
308 gcryalg
= GCRY_MD_SM3
;
312 rc
= GC_INVALID_HASH
;
322 gcrymode
= GCRY_MD_FLAG_HMAC
;
326 rc
= GC_INVALID_HASH
;
329 if (rc
== GC_OK
&& gcryalg
!= GCRY_MD_NONE
)
331 err
= gcry_md_open (&ctx
->gch
, gcryalg
, gcrymode
);
332 if (gcry_err_code (err
))
333 rc
= GC_INVALID_HASH
;
345 gc_hash_clone (gc_hash_handle handle
, gc_hash_handle
* outhandle
)
347 _gc_hash_ctx
*in
= handle
;
351 *outhandle
= out
= calloc (sizeof (*out
), 1);
353 return GC_MALLOC_ERROR
;
355 memcpy (out
, in
, sizeof (*out
));
357 err
= gcry_md_copy (&out
->gch
, in
->gch
);
361 return GC_INVALID_HASH
;
368 gc_hash_digest_length (Gc_hash hash
)
375 len
= GC_MD2_DIGEST_SIZE
;
379 len
= GC_MD4_DIGEST_SIZE
;
383 len
= GC_MD5_DIGEST_SIZE
;
387 len
= GC_RMD160_DIGEST_SIZE
;
391 len
= GC_SHA1_DIGEST_SIZE
;
395 len
= GC_SHA256_DIGEST_SIZE
;
399 len
= GC_SHA384_DIGEST_SIZE
;
403 len
= GC_SHA512_DIGEST_SIZE
;
407 len
= GC_SHA224_DIGEST_SIZE
;
411 len
= GC_SM3_DIGEST_SIZE
;
422 gc_hash_hmac_setkey (gc_hash_handle handle
, size_t len
, const char *key
)
424 _gc_hash_ctx
*ctx
= handle
;
426 if (ctx
->alg
!= GC_MD2
)
428 gcry_md_setkey (ctx
->gch
, key
, len
);
432 gc_hash_write (gc_hash_handle handle
, size_t len
, const char *data
)
434 _gc_hash_ctx
*ctx
= handle
;
437 if (ctx
->alg
== GC_MD2
)
438 md2_process_bytes (data
, len
, &ctx
->md2Context
);
441 gcry_md_write (ctx
->gch
, data
, len
);
445 gc_hash_read (gc_hash_handle handle
)
447 _gc_hash_ctx
*ctx
= handle
;
451 if (ctx
->alg
== GC_MD2
)
453 md2_finish_ctx (&ctx
->md2Context
, ctx
->hash
);
459 gcry_md_final (ctx
->gch
);
460 digest
= (const char *) gcry_md_read (ctx
->gch
, 0);
467 gc_hash_close (gc_hash_handle handle
)
469 _gc_hash_ctx
*ctx
= handle
;
472 if (ctx
->alg
!= GC_MD2
)
474 gcry_md_close (ctx
->gch
);
480 gc_hash_buffer (Gc_hash hash
, const void *in
, size_t inlen
, char *resbuf
)
488 md2_buffer (in
, inlen
, resbuf
);
495 gcryalg
= GCRY_MD_MD4
;
501 gcryalg
= GCRY_MD_MD5
;
505 #ifdef GNULIB_GC_SHA1
507 gcryalg
= GCRY_MD_SHA1
;
511 #ifdef GNULIB_GC_SHA256
513 gcryalg
= GCRY_MD_SHA256
;
517 #ifdef GNULIB_GC_SHA384
519 gcryalg
= GCRY_MD_SHA384
;
523 #ifdef GNULIB_GC_SHA512
525 gcryalg
= GCRY_MD_SHA512
;
529 #ifdef GNULIB_GC_SHA224
531 gcryalg
= GCRY_MD_SHA224
;
535 #ifdef GNULIB_GC_RMD160
537 gcryalg
= GCRY_MD_RMD160
;
543 gcryalg
= GCRY_MD_SM3
;
548 return GC_INVALID_HASH
;
551 gcry_md_hash_buffer (gcryalg
, resbuf
, in
, inlen
);
556 /* One-call interface. */
560 gc_md2 (const void *in
, size_t inlen
, void *resbuf
)
562 md2_buffer (in
, inlen
, resbuf
);
569 gc_md4 (const void *in
, size_t inlen
, void *resbuf
)
571 size_t outlen
= gcry_md_get_algo_dlen (GCRY_MD_MD4
);
576 assert (outlen
== GC_MD4_DIGEST_SIZE
);
578 err
= gcry_md_open (&hd
, GCRY_MD_MD4
, 0);
579 if (err
!= GPG_ERR_NO_ERROR
)
580 return GC_INVALID_HASH
;
582 gcry_md_write (hd
, in
, inlen
);
584 p
= gcry_md_read (hd
, GCRY_MD_MD4
);
588 return GC_INVALID_HASH
;
591 memcpy (resbuf
, p
, outlen
);
601 gc_md5 (const void *in
, size_t inlen
, void *resbuf
)
603 size_t outlen
= gcry_md_get_algo_dlen (GCRY_MD_MD5
);
608 assert (outlen
== GC_MD5_DIGEST_SIZE
);
610 err
= gcry_md_open (&hd
, GCRY_MD_MD5
, 0);
611 if (err
!= GPG_ERR_NO_ERROR
)
612 return GC_INVALID_HASH
;
614 gcry_md_write (hd
, in
, inlen
);
616 p
= gcry_md_read (hd
, GCRY_MD_MD5
);
620 return GC_INVALID_HASH
;
623 memcpy (resbuf
, p
, outlen
);
631 #ifdef GNULIB_GC_SHA1
633 gc_sha1 (const void *in
, size_t inlen
, void *resbuf
)
635 size_t outlen
= gcry_md_get_algo_dlen (GCRY_MD_SHA1
);
640 assert (outlen
== GC_SHA1_DIGEST_SIZE
);
642 err
= gcry_md_open (&hd
, GCRY_MD_SHA1
, 0);
643 if (err
!= GPG_ERR_NO_ERROR
)
644 return GC_INVALID_HASH
;
646 gcry_md_write (hd
, in
, inlen
);
648 p
= gcry_md_read (hd
, GCRY_MD_SHA1
);
652 return GC_INVALID_HASH
;
655 memcpy (resbuf
, p
, outlen
);
665 gc_sm3 (const void *in
, size_t inlen
, void *resbuf
)
667 size_t outlen
= gcry_md_get_algo_dlen (GCRY_MD_SM3
);
672 assert (outlen
== GC_SM3_DIGEST_SIZE
);
674 err
= gcry_md_open (&hd
, GCRY_MD_SM3
, 0);
675 if (err
!= GPG_ERR_NO_ERROR
)
676 return GC_INVALID_HASH
;
678 gcry_md_write (hd
, in
, inlen
);
680 p
= gcry_md_read (hd
, GCRY_MD_SM3
);
684 return GC_INVALID_HASH
;
687 memcpy (resbuf
, p
, outlen
);
695 #ifdef GNULIB_GC_HMAC_MD5
697 gc_hmac_md5 (const void *key
, size_t keylen
,
698 const void *in
, size_t inlen
, char *resbuf
)
700 size_t hlen
= gcry_md_get_algo_dlen (GCRY_MD_MD5
);
705 assert (hlen
== GC_MD5_DIGEST_SIZE
);
707 err
= gcry_md_open (&mdh
, GCRY_MD_MD5
, GCRY_MD_FLAG_HMAC
);
708 if (err
!= GPG_ERR_NO_ERROR
)
709 return GC_INVALID_HASH
;
711 err
= gcry_md_setkey (mdh
, key
, keylen
);
712 if (err
!= GPG_ERR_NO_ERROR
)
715 return GC_INVALID_HASH
;
718 gcry_md_write (mdh
, in
, inlen
);
720 hash
= gcry_md_read (mdh
, GCRY_MD_MD5
);
724 return GC_INVALID_HASH
;
727 memcpy (resbuf
, hash
, hlen
);
735 #ifdef GNULIB_GC_HMAC_SHA1
737 gc_hmac_sha1 (const void *key
, size_t keylen
,
738 const void *in
, size_t inlen
, char *resbuf
)
740 size_t hlen
= gcry_md_get_algo_dlen (GCRY_MD_SHA1
);
745 assert (hlen
== GC_SHA1_DIGEST_SIZE
);
747 err
= gcry_md_open (&mdh
, GCRY_MD_SHA1
, GCRY_MD_FLAG_HMAC
);
748 if (err
!= GPG_ERR_NO_ERROR
)
749 return GC_INVALID_HASH
;
751 err
= gcry_md_setkey (mdh
, key
, keylen
);
752 if (err
!= GPG_ERR_NO_ERROR
)
755 return GC_INVALID_HASH
;
758 gcry_md_write (mdh
, in
, inlen
);
760 hash
= gcry_md_read (mdh
, GCRY_MD_SHA1
);
764 return GC_INVALID_HASH
;
767 memcpy (resbuf
, hash
, hlen
);
775 #ifdef GNULIB_GC_HMAC_SHA256
777 gc_hmac_sha256 (const void *key
, size_t keylen
,
778 const void *in
, size_t inlen
, char *resbuf
)
780 size_t hlen
= gcry_md_get_algo_dlen (GCRY_MD_SHA256
);
785 assert (hlen
== GC_SHA256_DIGEST_SIZE
);
787 err
= gcry_md_open (&mdh
, GCRY_MD_SHA256
, GCRY_MD_FLAG_HMAC
);
788 if (err
!= GPG_ERR_NO_ERROR
)
789 return GC_INVALID_HASH
;
791 err
= gcry_md_setkey (mdh
, key
, keylen
);
792 if (err
!= GPG_ERR_NO_ERROR
)
795 return GC_INVALID_HASH
;
798 gcry_md_write (mdh
, in
, inlen
);
800 hash
= gcry_md_read (mdh
, GCRY_MD_SHA256
);
804 return GC_INVALID_HASH
;
807 memcpy (resbuf
, hash
, hlen
);
815 #ifdef GNULIB_GC_HMAC_SHA512
817 gc_hmac_sha512 (const void *key
, size_t keylen
,
818 const void *in
, size_t inlen
, char *resbuf
)
820 size_t hlen
= gcry_md_get_algo_dlen (GCRY_MD_SHA512
);
825 assert (hlen
== GC_SHA512_DIGEST_SIZE
);
827 err
= gcry_md_open (&mdh
, GCRY_MD_SHA512
, GCRY_MD_FLAG_HMAC
);
828 if (err
!= GPG_ERR_NO_ERROR
)
829 return GC_INVALID_HASH
;
831 err
= gcry_md_setkey (mdh
, key
, keylen
);
832 if (err
!= GPG_ERR_NO_ERROR
)
835 return GC_INVALID_HASH
;
838 gcry_md_write (mdh
, in
, inlen
);
840 hash
= gcry_md_read (mdh
, GCRY_MD_SHA512
);
844 return GC_INVALID_HASH
;
847 memcpy (resbuf
, hash
, hlen
);