1 /* gc-libgcrypt.c --- Crypto wrappers around Libgcrypt for GC.
2 * Copyright (C) 2002-2020 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. */
32 /* libgcrypt declares GCRY_MD_MD2 but does not actually implement the
33 MD2 algorithm. Therefore take the implementation from gnulib. */
36 #if GNULIB_GC_SM3 && !LIBGCRYPT_HAS_MD_SM3
42 #ifndef MIN_GCRYPT_VERSION
43 # define MIN_GCRYPT_VERSION "1.4.4"
53 err
= gcry_control (GCRYCTL_ANY_INITIALIZATION_P
);
54 if (err
== GPG_ERR_NO_ERROR
)
56 if (gcry_control (GCRYCTL_DISABLE_SECMEM
, NULL
, 0))
59 if (gcry_check_version (MIN_GCRYPT_VERSION
) == NULL
)
62 err
= gcry_control (GCRYCTL_INITIALIZATION_FINISHED
, NULL
, 0);
63 if (err
!= GPG_ERR_NO_ERROR
)
81 gc_nonce (char *data
, size_t datalen
)
83 gcry_create_nonce ((unsigned char *) data
, datalen
);
88 gc_pseudo_random (char *data
, size_t datalen
)
90 gcry_randomize ((unsigned char *) data
, datalen
, GCRY_STRONG_RANDOM
);
95 gc_random (char *data
, size_t datalen
)
97 gcry_randomize ((unsigned char *) data
, datalen
, GCRY_VERY_STRONG_RANDOM
);
103 /* Memory allocation. */
106 gc_set_allocators (gc_malloc_t func_malloc
,
107 gc_malloc_t secure_malloc
,
108 gc_secure_check_t secure_check
,
109 gc_realloc_t func_realloc
, gc_free_t func_free
)
111 gcry_set_allocation_handler (func_malloc
, secure_malloc
, secure_check
,
112 func_realloc
, func_free
);
118 gc_cipher_open (Gc_cipher alg
, Gc_cipher_mode mode
,
119 gc_cipher_handle
* outhandle
)
121 int gcryalg
, gcrymode
;
127 gcryalg
= GCRY_CIPHER_RIJNDAEL
;
131 gcryalg
= GCRY_CIPHER_RIJNDAEL
;
135 gcryalg
= GCRY_CIPHER_RIJNDAEL256
;
139 gcryalg
= GCRY_CIPHER_3DES
;
143 gcryalg
= GCRY_CIPHER_DES
;
148 gcryalg
= GCRY_CIPHER_ARCFOUR
;
152 gcryalg
= GCRY_CIPHER_RFC2268_40
;
157 gcryalg
= GCRY_CIPHER_CAMELLIA128
;
161 gcryalg
= GCRY_CIPHER_CAMELLIA256
;
166 return GC_INVALID_CIPHER
;
172 gcrymode
= GCRY_CIPHER_MODE_ECB
;
176 gcrymode
= GCRY_CIPHER_MODE_CBC
;
180 gcrymode
= GCRY_CIPHER_MODE_STREAM
;
184 return GC_INVALID_CIPHER
;
187 err
= gcry_cipher_open ((gcry_cipher_hd_t
*) outhandle
,
188 gcryalg
, gcrymode
, 0);
189 if (gcry_err_code (err
))
190 return GC_INVALID_CIPHER
;
196 gc_cipher_setkey (gc_cipher_handle handle
, size_t keylen
, const char *key
)
200 err
= gcry_cipher_setkey ((gcry_cipher_hd_t
) handle
, key
, keylen
);
201 if (gcry_err_code (err
))
202 return GC_INVALID_CIPHER
;
208 gc_cipher_setiv (gc_cipher_handle handle
, size_t ivlen
, const char *iv
)
212 err
= gcry_cipher_setiv ((gcry_cipher_hd_t
) handle
, iv
, ivlen
);
213 if (gcry_err_code (err
))
214 return GC_INVALID_CIPHER
;
220 gc_cipher_encrypt_inline (gc_cipher_handle handle
, size_t len
, char *data
)
222 if (gcry_cipher_encrypt ((gcry_cipher_hd_t
) handle
,
223 data
, len
, NULL
, len
) != 0)
224 return GC_INVALID_CIPHER
;
230 gc_cipher_decrypt_inline (gc_cipher_handle handle
, size_t len
, char *data
)
232 if (gcry_cipher_decrypt ((gcry_cipher_hd_t
) handle
,
233 data
, len
, NULL
, len
) != 0)
234 return GC_INVALID_CIPHER
;
240 gc_cipher_close (gc_cipher_handle handle
)
242 gcry_cipher_close (handle
);
249 /* Maximum of GC_MD2_DIGEST_SIZE and GC_SM3_DIGEST_SIZE. */
250 #define MAX_DIGEST_SIZE 32
252 typedef struct _gc_hash_ctx
{
256 #if GNULIB_GC_MD2 || (GNULIB_GC_SM3 && !LIBGCRYPT_HAS_MD_SM3)
257 char hash
[MAX_DIGEST_SIZE
];
260 struct md2_ctx md2Context
;
262 #if GNULIB_GC_SM3 && !LIBGCRYPT_HAS_MD_SM3
263 struct sm3_ctx sm3Context
;
268 gc_hash_open (Gc_hash hash
, Gc_hash_mode mode
, gc_hash_handle
* outhandle
)
271 int gcryalg
= 0, gcrymode
= 0;
275 ctx
= calloc (sizeof (*ctx
), 1);
277 return GC_MALLOC_ERROR
;
286 /* Not needed, because ctx is already zero-initialized. */
287 /*md2_init_ctx (&ctx->md2Context);*/
288 gcryalg
= GCRY_MD_NONE
;
293 gcryalg
= GCRY_MD_MD4
;
297 gcryalg
= GCRY_MD_MD5
;
301 gcryalg
= GCRY_MD_SHA1
;
305 gcryalg
= GCRY_MD_SHA256
;
309 gcryalg
= GCRY_MD_SHA384
;
313 gcryalg
= GCRY_MD_SHA512
;
317 gcryalg
= GCRY_MD_SHA224
;
321 gcryalg
= GCRY_MD_RMD160
;
326 # if LIBGCRYPT_HAS_MD_SM3
327 gcryalg
= GCRY_MD_SM3
;
329 sm3_init_ctx (&ctx
->sm3Context
);
330 gcryalg
= GCRY_MD_NONE
;
336 rc
= GC_INVALID_HASH
;
346 gcrymode
= GCRY_MD_FLAG_HMAC
;
350 rc
= GC_INVALID_HASH
;
353 if (rc
== GC_OK
&& gcryalg
!= GCRY_MD_NONE
)
355 err
= gcry_md_open (&ctx
->gch
, gcryalg
, gcrymode
);
356 if (gcry_err_code (err
))
357 rc
= GC_INVALID_HASH
;
369 gc_hash_clone (gc_hash_handle handle
, gc_hash_handle
* outhandle
)
371 _gc_hash_ctx
*in
= handle
;
375 *outhandle
= out
= calloc (sizeof (*out
), 1);
377 return GC_MALLOC_ERROR
;
379 memcpy (out
, in
, sizeof (*out
));
381 err
= gcry_md_copy (&out
->gch
, in
->gch
);
385 return GC_INVALID_HASH
;
392 gc_hash_digest_length (Gc_hash hash
)
399 len
= GC_MD2_DIGEST_SIZE
;
403 len
= GC_MD4_DIGEST_SIZE
;
407 len
= GC_MD5_DIGEST_SIZE
;
411 len
= GC_RMD160_DIGEST_SIZE
;
415 len
= GC_SHA1_DIGEST_SIZE
;
419 len
= GC_SHA256_DIGEST_SIZE
;
423 len
= GC_SHA384_DIGEST_SIZE
;
427 len
= GC_SHA512_DIGEST_SIZE
;
431 len
= GC_SHA224_DIGEST_SIZE
;
435 len
= GC_SM3_DIGEST_SIZE
;
446 gc_hash_hmac_setkey (gc_hash_handle handle
, size_t len
, const char *key
)
448 _gc_hash_ctx
*ctx
= handle
;
450 if (ctx
->alg
!= GC_MD2
)
452 #if GNULIB_GC_SM3 && !LIBGCRYPT_HAS_MD_SM3
453 if (ctx
->alg
!= GC_SM3
)
455 gcry_md_setkey (ctx
->gch
, key
, len
);
459 gc_hash_write (gc_hash_handle handle
, size_t len
, const char *data
)
461 _gc_hash_ctx
*ctx
= handle
;
464 if (ctx
->alg
== GC_MD2
)
465 md2_process_bytes (data
, len
, &ctx
->md2Context
);
468 #if GNULIB_GC_SM3 && !LIBGCRYPT_HAS_MD_SM3
469 if (ctx
->alg
== GC_SM3
)
470 sm3_process_bytes (data
, len
, &ctx
->sm3Context
);
473 gcry_md_write (ctx
->gch
, data
, len
);
477 gc_hash_read (gc_hash_handle handle
)
479 _gc_hash_ctx
*ctx
= handle
;
483 if (ctx
->alg
== GC_MD2
)
485 md2_finish_ctx (&ctx
->md2Context
, ctx
->hash
);
490 #if GNULIB_GC_SM3 && !LIBGCRYPT_HAS_MD_SM3
491 if (ctx
->alg
== GC_SM3
)
493 sm3_finish_ctx (&ctx
->sm3Context
, ctx
->hash
);
499 gcry_md_final (ctx
->gch
);
500 digest
= (const char *) gcry_md_read (ctx
->gch
, 0);
507 gc_hash_close (gc_hash_handle handle
)
509 _gc_hash_ctx
*ctx
= handle
;
512 if (ctx
->alg
!= GC_MD2
)
514 #if GNULIB_GC_SM3 && !LIBGCRYPT_HAS_MD_SM3
515 if (ctx
->alg
!= GC_SM3
)
517 gcry_md_close (ctx
->gch
);
523 gc_hash_buffer (Gc_hash hash
, const void *in
, size_t inlen
, char *resbuf
)
531 md2_buffer (in
, inlen
, resbuf
);
537 gcryalg
= GCRY_MD_MD4
;
543 gcryalg
= GCRY_MD_MD5
;
549 gcryalg
= GCRY_MD_SHA1
;
555 gcryalg
= GCRY_MD_SHA256
;
561 gcryalg
= GCRY_MD_SHA384
;
567 gcryalg
= GCRY_MD_SHA512
;
573 gcryalg
= GCRY_MD_SHA224
;
579 gcryalg
= GCRY_MD_RMD160
;
585 # if !LIBGCRYPT_HAS_MD_SM3
586 sm3_buffer (in
, inlen
, resbuf
);
589 gcryalg
= GCRY_MD_SM3
;
595 return GC_INVALID_HASH
;
598 gcry_md_hash_buffer (gcryalg
, resbuf
, in
, inlen
);
603 /* One-call interface. */
607 gc_md2 (const void *in
, size_t inlen
, void *resbuf
)
609 md2_buffer (in
, inlen
, resbuf
);
616 gc_md4 (const void *in
, size_t inlen
, void *resbuf
)
618 size_t outlen
= gcry_md_get_algo_dlen (GCRY_MD_MD4
);
623 assert (outlen
== GC_MD4_DIGEST_SIZE
);
625 err
= gcry_md_open (&hd
, GCRY_MD_MD4
, 0);
626 if (err
!= GPG_ERR_NO_ERROR
)
627 return GC_INVALID_HASH
;
629 gcry_md_write (hd
, in
, inlen
);
631 p
= gcry_md_read (hd
, GCRY_MD_MD4
);
635 return GC_INVALID_HASH
;
638 memcpy (resbuf
, p
, outlen
);
648 gc_md5 (const void *in
, size_t inlen
, void *resbuf
)
650 size_t outlen
= gcry_md_get_algo_dlen (GCRY_MD_MD5
);
655 assert (outlen
== GC_MD5_DIGEST_SIZE
);
657 err
= gcry_md_open (&hd
, GCRY_MD_MD5
, 0);
658 if (err
!= GPG_ERR_NO_ERROR
)
659 return GC_INVALID_HASH
;
661 gcry_md_write (hd
, in
, inlen
);
663 p
= gcry_md_read (hd
, GCRY_MD_MD5
);
667 return GC_INVALID_HASH
;
670 memcpy (resbuf
, p
, outlen
);
680 gc_sha1 (const void *in
, size_t inlen
, void *resbuf
)
682 size_t outlen
= gcry_md_get_algo_dlen (GCRY_MD_SHA1
);
687 assert (outlen
== GC_SHA1_DIGEST_SIZE
);
689 err
= gcry_md_open (&hd
, GCRY_MD_SHA1
, 0);
690 if (err
!= GPG_ERR_NO_ERROR
)
691 return GC_INVALID_HASH
;
693 gcry_md_write (hd
, in
, inlen
);
695 p
= gcry_md_read (hd
, GCRY_MD_SHA1
);
699 return GC_INVALID_HASH
;
702 memcpy (resbuf
, p
, outlen
);
712 gc_sha256 (const void *in
, size_t inlen
, void *resbuf
)
714 size_t outlen
= gcry_md_get_algo_dlen (GCRY_MD_SHA256
);
719 assert (outlen
== GC_SHA256_DIGEST_SIZE
);
721 err
= gcry_md_open (&hd
, GCRY_MD_SHA256
, 0);
722 if (err
!= GPG_ERR_NO_ERROR
)
723 return GC_INVALID_HASH
;
725 gcry_md_write (hd
, in
, inlen
);
727 p
= gcry_md_read (hd
, GCRY_MD_SHA256
);
731 return GC_INVALID_HASH
;
734 memcpy (resbuf
, p
, outlen
);
744 gc_sha512 (const void *in
, size_t inlen
, void *resbuf
)
746 size_t outlen
= gcry_md_get_algo_dlen (GCRY_MD_SHA512
);
751 assert (outlen
== GC_SHA512_DIGEST_SIZE
);
753 err
= gcry_md_open (&hd
, GCRY_MD_SHA512
, 0);
754 if (err
!= GPG_ERR_NO_ERROR
)
755 return GC_INVALID_HASH
;
757 gcry_md_write (hd
, in
, inlen
);
759 p
= gcry_md_read (hd
, GCRY_MD_SHA512
);
763 return GC_INVALID_HASH
;
766 memcpy (resbuf
, p
, outlen
);
776 gc_sm3 (const void *in
, size_t inlen
, void *resbuf
)
778 # if !LIBGCRYPT_HAS_MD_SM3
779 sm3_buffer (in
, inlen
, resbuf
);
782 size_t outlen
= gcry_md_get_algo_dlen (GCRY_MD_SM3
);
787 assert (outlen
== GC_SM3_DIGEST_SIZE
);
789 err
= gcry_md_open (&hd
, GCRY_MD_SM3
, 0);
790 if (err
!= GPG_ERR_NO_ERROR
)
791 return GC_INVALID_HASH
;
793 gcry_md_write (hd
, in
, inlen
);
795 p
= gcry_md_read (hd
, GCRY_MD_SM3
);
799 return GC_INVALID_HASH
;
802 memcpy (resbuf
, p
, outlen
);
811 #if GNULIB_GC_HMAC_MD5
813 gc_hmac_md5 (const void *key
, size_t keylen
,
814 const void *in
, size_t inlen
, char *resbuf
)
816 size_t hlen
= gcry_md_get_algo_dlen (GCRY_MD_MD5
);
821 assert (hlen
== GC_MD5_DIGEST_SIZE
);
823 err
= gcry_md_open (&mdh
, GCRY_MD_MD5
, GCRY_MD_FLAG_HMAC
);
824 if (err
!= GPG_ERR_NO_ERROR
)
825 return GC_INVALID_HASH
;
827 err
= gcry_md_setkey (mdh
, key
, keylen
);
828 if (err
!= GPG_ERR_NO_ERROR
)
831 return GC_INVALID_HASH
;
834 gcry_md_write (mdh
, in
, inlen
);
836 hash
= gcry_md_read (mdh
, GCRY_MD_MD5
);
840 return GC_INVALID_HASH
;
843 memcpy (resbuf
, hash
, hlen
);
851 #if GNULIB_GC_HMAC_SHA1
853 gc_hmac_sha1 (const void *key
, size_t keylen
,
854 const void *in
, size_t inlen
, char *resbuf
)
856 size_t hlen
= gcry_md_get_algo_dlen (GCRY_MD_SHA1
);
861 assert (hlen
== GC_SHA1_DIGEST_SIZE
);
863 err
= gcry_md_open (&mdh
, GCRY_MD_SHA1
, GCRY_MD_FLAG_HMAC
);
864 if (err
!= GPG_ERR_NO_ERROR
)
865 return GC_INVALID_HASH
;
867 err
= gcry_md_setkey (mdh
, key
, keylen
);
868 if (err
!= GPG_ERR_NO_ERROR
)
871 return GC_INVALID_HASH
;
874 gcry_md_write (mdh
, in
, inlen
);
876 hash
= gcry_md_read (mdh
, GCRY_MD_SHA1
);
880 return GC_INVALID_HASH
;
883 memcpy (resbuf
, hash
, hlen
);
891 #if GNULIB_GC_HMAC_SHA256
893 gc_hmac_sha256 (const void *key
, size_t keylen
,
894 const void *in
, size_t inlen
, char *resbuf
)
896 size_t hlen
= gcry_md_get_algo_dlen (GCRY_MD_SHA256
);
901 assert (hlen
== GC_SHA256_DIGEST_SIZE
);
903 err
= gcry_md_open (&mdh
, GCRY_MD_SHA256
, GCRY_MD_FLAG_HMAC
);
904 if (err
!= GPG_ERR_NO_ERROR
)
905 return GC_INVALID_HASH
;
907 err
= gcry_md_setkey (mdh
, key
, keylen
);
908 if (err
!= GPG_ERR_NO_ERROR
)
911 return GC_INVALID_HASH
;
914 gcry_md_write (mdh
, in
, inlen
);
916 hash
= gcry_md_read (mdh
, GCRY_MD_SHA256
);
920 return GC_INVALID_HASH
;
923 memcpy (resbuf
, hash
, hlen
);
931 #if GNULIB_GC_HMAC_SHA512
933 gc_hmac_sha512 (const void *key
, size_t keylen
,
934 const void *in
, size_t inlen
, char *resbuf
)
936 size_t hlen
= gcry_md_get_algo_dlen (GCRY_MD_SHA512
);
941 assert (hlen
== GC_SHA512_DIGEST_SIZE
);
943 err
= gcry_md_open (&mdh
, GCRY_MD_SHA512
, GCRY_MD_FLAG_HMAC
);
944 if (err
!= GPG_ERR_NO_ERROR
)
945 return GC_INVALID_HASH
;
947 err
= gcry_md_setkey (mdh
, key
, keylen
);
948 if (err
!= GPG_ERR_NO_ERROR
)
951 return GC_INVALID_HASH
;
954 gcry_md_write (mdh
, in
, inlen
);
956 hash
= gcry_md_read (mdh
, GCRY_MD_SHA512
);
960 return GC_INVALID_HASH
;
963 memcpy (resbuf
, hash
, hlen
);