exp2l: Work around a NetBSD 10.0/i386 bug.
[gnulib.git] / lib / gc-libgcrypt.c
blobcbe66a8b44c99b106f58b5dfb42f4edd7519e96c
1 /* gc-libgcrypt.c --- Crypto wrappers around Libgcrypt for GC.
2 * Copyright (C) 2002-2024 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 Lesser General Public License as
6 * published by the Free Software Foundation; either version 2.1 of the
7 * License, or (at your option) any later version.
9 * This file is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 /* Note: This file is only built if GC uses Libgcrypt. */
21 #include <config.h>
23 /* Get prototype. */
24 #include "gc.h"
26 #include <stdlib.h>
27 #include <string.h>
29 /* Get libgcrypt API. */
30 #include <gcrypt.h>
31 #if GNULIB_GC_MD2
32 /* libgcrypt declares GCRY_MD_MD2 but does not actually implement the
33 MD2 algorithm. Therefore take the implementation from gnulib. */
34 # include "md2.h"
35 #endif
36 #if GNULIB_GC_SM3 && !LIBGCRYPT_HAS_MD_SM3
37 # include "sm3.h"
38 #endif
40 #include <assert.h>
42 #ifndef MIN_GCRYPT_VERSION
43 # define MIN_GCRYPT_VERSION "1.4.4"
44 #endif
46 /* Initialization. */
48 Gc_rc
49 gc_init (void)
51 gcry_error_t err;
53 err = gcry_control (GCRYCTL_ANY_INITIALIZATION_P);
54 if (err == GPG_ERR_NO_ERROR)
56 if (gcry_control (GCRYCTL_DISABLE_SECMEM, NULL, 0))
57 return GC_INIT_ERROR;
59 if (gcry_check_version (MIN_GCRYPT_VERSION) == NULL)
60 return GC_INIT_ERROR;
62 err = gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL, 0);
63 if (err != GPG_ERR_NO_ERROR)
64 return GC_INIT_ERROR;
67 return GC_OK;
70 void
71 gc_done (void)
73 return;
76 #if GNULIB_GC_RANDOM
78 /* Randomness. */
80 Gc_rc
81 gc_nonce (char *data, size_t datalen)
83 gcry_create_nonce ((unsigned char *) data, datalen);
84 return GC_OK;
87 Gc_rc
88 gc_pseudo_random (char *data, size_t datalen)
90 gcry_randomize ((unsigned char *) data, datalen, GCRY_STRONG_RANDOM);
91 return GC_OK;
94 Gc_rc
95 gc_random (char *data, size_t datalen)
97 gcry_randomize ((unsigned char *) data, datalen, GCRY_VERY_STRONG_RANDOM);
98 return GC_OK;
101 #endif
103 /* Memory allocation. */
105 void
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);
115 /* Ciphers. */
117 Gc_rc
118 gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode,
119 gc_cipher_handle * outhandle)
121 int gcryalg, gcrymode;
122 gcry_error_t err;
124 switch (alg)
126 case GC_AES128:
127 gcryalg = GCRY_CIPHER_RIJNDAEL;
128 break;
130 case GC_AES192:
131 gcryalg = GCRY_CIPHER_RIJNDAEL;
132 break;
134 case GC_AES256:
135 gcryalg = GCRY_CIPHER_RIJNDAEL256;
136 break;
138 case GC_3DES:
139 gcryalg = GCRY_CIPHER_3DES;
140 break;
142 case GC_DES:
143 gcryalg = GCRY_CIPHER_DES;
144 break;
146 case GC_ARCFOUR128:
147 case GC_ARCFOUR40:
148 gcryalg = GCRY_CIPHER_ARCFOUR;
149 break;
151 case GC_ARCTWO40:
152 gcryalg = GCRY_CIPHER_RFC2268_40;
153 break;
155 #ifdef HAVE_CAMELLIA
156 case GC_CAMELLIA128:
157 gcryalg = GCRY_CIPHER_CAMELLIA128;
158 break;
160 case GC_CAMELLIA256:
161 gcryalg = GCRY_CIPHER_CAMELLIA256;
162 break;
163 #endif
165 default:
166 return GC_INVALID_CIPHER;
169 switch (mode)
171 case GC_ECB:
172 gcrymode = GCRY_CIPHER_MODE_ECB;
173 break;
175 case GC_CBC:
176 gcrymode = GCRY_CIPHER_MODE_CBC;
177 break;
179 case GC_STREAM:
180 gcrymode = GCRY_CIPHER_MODE_STREAM;
181 break;
183 default:
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;
192 return GC_OK;
195 Gc_rc
196 gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key)
198 gcry_error_t err;
200 err = gcry_cipher_setkey ((gcry_cipher_hd_t) handle, key, keylen);
201 if (gcry_err_code (err))
202 return GC_INVALID_CIPHER;
204 return GC_OK;
207 Gc_rc
208 gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv)
210 gcry_error_t err;
212 err = gcry_cipher_setiv ((gcry_cipher_hd_t) handle, iv, ivlen);
213 if (gcry_err_code (err))
214 return GC_INVALID_CIPHER;
216 return GC_OK;
219 Gc_rc
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;
226 return GC_OK;
229 Gc_rc
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;
236 return GC_OK;
239 Gc_rc
240 gc_cipher_close (gc_cipher_handle handle)
242 gcry_cipher_close (handle);
244 return GC_OK;
247 /* Hashes. */
249 /* Maximum of GC_MD2_DIGEST_SIZE and GC_SM3_DIGEST_SIZE. */
250 #define MAX_DIGEST_SIZE 32
252 typedef struct _gc_hash_ctx {
253 Gc_hash alg;
254 Gc_hash_mode mode;
255 gcry_md_hd_t gch;
256 #if GNULIB_GC_MD2 || (GNULIB_GC_SM3 && !LIBGCRYPT_HAS_MD_SM3)
257 char hash[MAX_DIGEST_SIZE];
258 #endif
259 #if GNULIB_GC_MD2
260 struct md2_ctx md2Context;
261 #endif
262 #if GNULIB_GC_SM3 && !LIBGCRYPT_HAS_MD_SM3
263 struct sm3_ctx sm3Context;
264 #endif
265 } _gc_hash_ctx;
267 Gc_rc
268 gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle)
270 _gc_hash_ctx *ctx;
271 int gcryalg = 0, gcrymode = 0;
272 gcry_error_t err;
273 Gc_rc rc = GC_OK;
275 ctx = calloc (sizeof (*ctx), 1);
276 if (!ctx)
277 return GC_MALLOC_ERROR;
279 ctx->alg = hash;
280 ctx->mode = mode;
282 switch (hash)
284 #if GNULIB_GC_MD2
285 case GC_MD2:
286 /* Not needed, because ctx is already zero-initialized. */
287 /*md2_init_ctx (&ctx->md2Context);*/
288 gcryalg = GCRY_MD_NONE;
289 break;
290 #endif
292 case GC_MD4:
293 gcryalg = GCRY_MD_MD4;
294 break;
296 case GC_MD5:
297 gcryalg = GCRY_MD_MD5;
298 break;
300 case GC_SHA1:
301 gcryalg = GCRY_MD_SHA1;
302 break;
304 case GC_SHA256:
305 gcryalg = GCRY_MD_SHA256;
306 break;
308 case GC_SHA384:
309 gcryalg = GCRY_MD_SHA384;
310 break;
312 case GC_SHA512:
313 gcryalg = GCRY_MD_SHA512;
314 break;
316 case GC_SHA224:
317 gcryalg = GCRY_MD_SHA224;
318 break;
320 case GC_RMD160:
321 gcryalg = GCRY_MD_RMD160;
322 break;
324 #if GNULIB_GC_SM3
325 case GC_SM3:
326 # if LIBGCRYPT_HAS_MD_SM3
327 gcryalg = GCRY_MD_SM3;
328 # else
329 sm3_init_ctx (&ctx->sm3Context);
330 gcryalg = GCRY_MD_NONE;
331 # endif
332 break;
333 #endif
335 default:
336 rc = GC_INVALID_HASH;
339 switch (mode)
341 case GC_NULL:
342 gcrymode = 0;
343 break;
345 case GC_HMAC:
346 gcrymode = GCRY_MD_FLAG_HMAC;
347 break;
349 default:
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;
360 if (rc == GC_OK)
361 *outhandle = ctx;
362 else
363 free (ctx);
365 return rc;
368 Gc_rc
369 gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle)
371 _gc_hash_ctx *in = handle;
372 _gc_hash_ctx *out;
373 int err;
375 *outhandle = out = calloc (sizeof (*out), 1);
376 if (!out)
377 return GC_MALLOC_ERROR;
379 memcpy (out, in, sizeof (*out));
381 err = gcry_md_copy (&out->gch, in->gch);
382 if (err)
384 free (out);
385 return GC_INVALID_HASH;
388 return GC_OK;
391 size_t
392 gc_hash_digest_length (Gc_hash hash)
394 size_t len;
396 switch (hash)
398 case GC_MD2:
399 len = GC_MD2_DIGEST_SIZE;
400 break;
402 case GC_MD4:
403 len = GC_MD4_DIGEST_SIZE;
404 break;
406 case GC_MD5:
407 len = GC_MD5_DIGEST_SIZE;
408 break;
410 case GC_RMD160:
411 len = GC_RMD160_DIGEST_SIZE;
412 break;
414 case GC_SHA1:
415 len = GC_SHA1_DIGEST_SIZE;
416 break;
418 case GC_SHA256:
419 len = GC_SHA256_DIGEST_SIZE;
420 break;
422 case GC_SHA384:
423 len = GC_SHA384_DIGEST_SIZE;
424 break;
426 case GC_SHA512:
427 len = GC_SHA512_DIGEST_SIZE;
428 break;
430 case GC_SHA224:
431 len = GC_SHA224_DIGEST_SIZE;
432 break;
434 case GC_SM3:
435 len = GC_SM3_DIGEST_SIZE;
436 break;
438 default:
439 return 0;
442 return len;
445 void
446 gc_hash_hmac_setkey (gc_hash_handle handle, size_t len, const char *key)
448 _gc_hash_ctx *ctx = handle;
449 #if GNULIB_GC_MD2
450 if (ctx->alg != GC_MD2)
451 #endif
452 #if GNULIB_GC_SM3 && !LIBGCRYPT_HAS_MD_SM3
453 if (ctx->alg != GC_SM3)
454 #endif
455 gcry_md_setkey (ctx->gch, key, len);
458 void
459 gc_hash_write (gc_hash_handle handle, size_t len, const char *data)
461 _gc_hash_ctx *ctx = handle;
463 #if GNULIB_GC_MD2
464 if (ctx->alg == GC_MD2)
465 md2_process_bytes (data, len, &ctx->md2Context);
466 else
467 #endif
468 #if GNULIB_GC_SM3 && !LIBGCRYPT_HAS_MD_SM3
469 if (ctx->alg == GC_SM3)
470 sm3_process_bytes (data, len, &ctx->sm3Context);
471 else
472 #endif
473 gcry_md_write (ctx->gch, data, len);
476 const char *
477 gc_hash_read (gc_hash_handle handle)
479 _gc_hash_ctx *ctx = handle;
480 const char *digest;
482 #if GNULIB_GC_MD2
483 if (ctx->alg == GC_MD2)
485 md2_finish_ctx (&ctx->md2Context, ctx->hash);
486 digest = ctx->hash;
488 else
489 #endif
490 #if GNULIB_GC_SM3 && !LIBGCRYPT_HAS_MD_SM3
491 if (ctx->alg == GC_SM3)
493 sm3_finish_ctx (&ctx->sm3Context, ctx->hash);
494 digest = ctx->hash;
496 else
497 #endif
499 gcry_md_final (ctx->gch);
500 digest = (const char *) gcry_md_read (ctx->gch, 0);
503 return digest;
506 void
507 gc_hash_close (gc_hash_handle handle)
509 _gc_hash_ctx *ctx = handle;
511 #if GNULIB_GC_MD2
512 if (ctx->alg != GC_MD2)
513 #endif
514 #if GNULIB_GC_SM3 && !LIBGCRYPT_HAS_MD_SM3
515 if (ctx->alg != GC_SM3)
516 #endif
517 gcry_md_close (ctx->gch);
519 free (ctx);
522 Gc_rc
523 gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf)
525 int gcryalg;
527 switch (hash)
529 #if GNULIB_GC_MD2
530 case GC_MD2:
531 md2_buffer (in, inlen, resbuf);
532 return GC_OK;
533 #endif
535 #if GNULIB_GC_MD4
536 case GC_MD4:
537 gcryalg = GCRY_MD_MD4;
538 break;
539 #endif
541 #if GNULIB_GC_MD5
542 case GC_MD5:
543 gcryalg = GCRY_MD_MD5;
544 break;
545 #endif
547 #if GNULIB_GC_SHA1
548 case GC_SHA1:
549 gcryalg = GCRY_MD_SHA1;
550 break;
551 #endif
553 #if GNULIB_GC_SHA256
554 case GC_SHA256:
555 gcryalg = GCRY_MD_SHA256;
556 break;
557 #endif
559 #if GNULIB_GC_SHA384
560 case GC_SHA384:
561 gcryalg = GCRY_MD_SHA384;
562 break;
563 #endif
565 #if GNULIB_GC_SHA512
566 case GC_SHA512:
567 gcryalg = GCRY_MD_SHA512;
568 break;
569 #endif
571 #if GNULIB_GC_SHA224
572 case GC_SHA224:
573 gcryalg = GCRY_MD_SHA224;
574 break;
575 #endif
577 #if GNULIB_GC_RMD160
578 case GC_RMD160:
579 gcryalg = GCRY_MD_RMD160;
580 break;
581 #endif
583 #if GNULIB_GC_SM3
584 case GC_SM3:
585 # if !LIBGCRYPT_HAS_MD_SM3
586 sm3_buffer (in, inlen, resbuf);
587 return GC_OK;
588 # else
589 gcryalg = GCRY_MD_SM3;
590 break;
591 # endif
592 #endif
594 default:
595 return GC_INVALID_HASH;
598 gcry_md_hash_buffer (gcryalg, resbuf, in, inlen);
600 return GC_OK;
603 /* One-call interface. */
605 #if GNULIB_GC_MD2
606 Gc_rc
607 gc_md2 (const void *in, size_t inlen, void *resbuf)
609 md2_buffer (in, inlen, resbuf);
610 return GC_OK;
612 #endif
614 #if GNULIB_GC_MD4
615 Gc_rc
616 gc_md4 (const void *in, size_t inlen, void *resbuf)
618 size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_MD4);
619 gcry_md_hd_t hd;
620 gpg_error_t err;
621 unsigned char *p;
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);
632 if (p == NULL)
634 gcry_md_close (hd);
635 return GC_INVALID_HASH;
638 memcpy (resbuf, p, outlen);
640 gcry_md_close (hd);
642 return GC_OK;
644 #endif
646 #if GNULIB_GC_MD5
647 Gc_rc
648 gc_md5 (const void *in, size_t inlen, void *resbuf)
650 size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_MD5);
651 gcry_md_hd_t hd;
652 gpg_error_t err;
653 unsigned char *p;
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);
664 if (p == NULL)
666 gcry_md_close (hd);
667 return GC_INVALID_HASH;
670 memcpy (resbuf, p, outlen);
672 gcry_md_close (hd);
674 return GC_OK;
676 #endif
678 #if GNULIB_GC_SHA1
679 Gc_rc
680 gc_sha1 (const void *in, size_t inlen, void *resbuf)
682 size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
683 gcry_md_hd_t hd;
684 gpg_error_t err;
685 unsigned char *p;
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);
696 if (p == NULL)
698 gcry_md_close (hd);
699 return GC_INVALID_HASH;
702 memcpy (resbuf, p, outlen);
704 gcry_md_close (hd);
706 return GC_OK;
708 #endif
710 #if GNULIB_GC_SHA256
711 Gc_rc
712 gc_sha256 (const void *in, size_t inlen, void *resbuf)
714 size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_SHA256);
715 gcry_md_hd_t hd;
716 gpg_error_t err;
717 unsigned char *p;
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);
728 if (p == NULL)
730 gcry_md_close (hd);
731 return GC_INVALID_HASH;
734 memcpy (resbuf, p, outlen);
736 gcry_md_close (hd);
738 return GC_OK;
740 #endif
742 #if GNULIB_GC_SHA512
743 Gc_rc
744 gc_sha512 (const void *in, size_t inlen, void *resbuf)
746 size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_SHA512);
747 gcry_md_hd_t hd;
748 gpg_error_t err;
749 unsigned char *p;
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);
760 if (p == NULL)
762 gcry_md_close (hd);
763 return GC_INVALID_HASH;
766 memcpy (resbuf, p, outlen);
768 gcry_md_close (hd);
770 return GC_OK;
772 #endif
774 #if GNULIB_GC_SM3
775 Gc_rc
776 gc_sm3 (const void *in, size_t inlen, void *resbuf)
778 # if !LIBGCRYPT_HAS_MD_SM3
779 sm3_buffer (in, inlen, resbuf);
780 return GC_OK;
781 # else
782 size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_SM3);
783 gcry_md_hd_t hd;
784 gpg_error_t err;
785 unsigned char *p;
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);
796 if (p == NULL)
798 gcry_md_close (hd);
799 return GC_INVALID_HASH;
802 memcpy (resbuf, p, outlen);
804 gcry_md_close (hd);
806 return GC_OK;
807 # endif
809 #endif
811 #if GNULIB_GC_HMAC_MD5
812 Gc_rc
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);
817 gcry_md_hd_t mdh;
818 unsigned char *hash;
819 gpg_error_t err;
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)
830 gcry_md_close (mdh);
831 return GC_INVALID_HASH;
834 gcry_md_write (mdh, in, inlen);
836 hash = gcry_md_read (mdh, GCRY_MD_MD5);
837 if (hash == NULL)
839 gcry_md_close (mdh);
840 return GC_INVALID_HASH;
843 memcpy (resbuf, hash, hlen);
845 gcry_md_close (mdh);
847 return GC_OK;
849 #endif
851 #if GNULIB_GC_HMAC_SHA1
852 Gc_rc
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);
857 gcry_md_hd_t mdh;
858 unsigned char *hash;
859 gpg_error_t err;
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)
870 gcry_md_close (mdh);
871 return GC_INVALID_HASH;
874 gcry_md_write (mdh, in, inlen);
876 hash = gcry_md_read (mdh, GCRY_MD_SHA1);
877 if (hash == NULL)
879 gcry_md_close (mdh);
880 return GC_INVALID_HASH;
883 memcpy (resbuf, hash, hlen);
885 gcry_md_close (mdh);
887 return GC_OK;
889 #endif
891 #if GNULIB_GC_HMAC_SHA256
892 Gc_rc
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);
897 gcry_md_hd_t mdh;
898 unsigned char *hash;
899 gpg_error_t err;
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)
910 gcry_md_close (mdh);
911 return GC_INVALID_HASH;
914 gcry_md_write (mdh, in, inlen);
916 hash = gcry_md_read (mdh, GCRY_MD_SHA256);
917 if (hash == NULL)
919 gcry_md_close (mdh);
920 return GC_INVALID_HASH;
923 memcpy (resbuf, hash, hlen);
925 gcry_md_close (mdh);
927 return GC_OK;
929 #endif
931 #if GNULIB_GC_HMAC_SHA512
932 Gc_rc
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);
937 gcry_md_hd_t mdh;
938 unsigned char *hash;
939 gpg_error_t err;
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)
950 gcry_md_close (mdh);
951 return GC_INVALID_HASH;
954 gcry_md_write (mdh, in, inlen);
956 hash = gcry_md_read (mdh, GCRY_MD_SHA512);
957 if (hash == NULL)
959 gcry_md_close (mdh);
960 return GC_INVALID_HASH;
963 memcpy (resbuf, hash, hlen);
965 gcry_md_close (mdh);
967 return GC_OK;
969 #endif