1 /* gc-libgcrypt.c --- Crypto wrappers around Libgcrypt for GC.
2  * Copyright (C) 2002-2021 Free Software Foundation, Inc.
3  *
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 published
6  * by the Free Software Foundation; either version 2.1, or (at your
7  * option) any later version.
8  *
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  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this file; if not, see <https://www.gnu.org/licenses/>.
16  *
17  */
18 
19 /* Note: This file is only built if GC uses Libgcrypt. */
20 
21 #include <config.h>
22 
23 /* Get prototype. */
24 #include "gc.h"
25 
26 #include <stdlib.h>
27 #include <string.h>
28 
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
39 
40 #include <assert.h>
41 
42 #ifndef MIN_GCRYPT_VERSION
43 # define MIN_GCRYPT_VERSION "1.4.4"
44 #endif
45 
46 /* Initialization. */
47 
48 Gc_rc
gc_init(void)49 gc_init (void)
50 {
51   gcry_error_t err;
52 
53   err = gcry_control (GCRYCTL_ANY_INITIALIZATION_P);
54   if (err == GPG_ERR_NO_ERROR)
55     {
56       if (gcry_control (GCRYCTL_DISABLE_SECMEM, NULL, 0))
57         return GC_INIT_ERROR;
58 
59       if (gcry_check_version (MIN_GCRYPT_VERSION) == NULL)
60         return GC_INIT_ERROR;
61 
62       err = gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL, 0);
63       if (err != GPG_ERR_NO_ERROR)
64         return GC_INIT_ERROR;
65     }
66 
67   return GC_OK;
68 }
69 
70 void
gc_done(void)71 gc_done (void)
72 {
73   return;
74 }
75 
76 #if GNULIB_GC_RANDOM
77 
78 /* Randomness. */
79 
80 Gc_rc
gc_nonce(char * data,size_t datalen)81 gc_nonce (char *data, size_t datalen)
82 {
83   gcry_create_nonce ((unsigned char *) data, datalen);
84   return GC_OK;
85 }
86 
87 Gc_rc
gc_pseudo_random(char * data,size_t datalen)88 gc_pseudo_random (char *data, size_t datalen)
89 {
90   gcry_randomize ((unsigned char *) data, datalen, GCRY_STRONG_RANDOM);
91   return GC_OK;
92 }
93 
94 Gc_rc
gc_random(char * data,size_t datalen)95 gc_random (char *data, size_t datalen)
96 {
97   gcry_randomize ((unsigned char *) data, datalen, GCRY_VERY_STRONG_RANDOM);
98   return GC_OK;
99 }
100 
101 #endif
102 
103 /* Memory allocation. */
104 
105 void
gc_set_allocators(gc_malloc_t func_malloc,gc_malloc_t secure_malloc,gc_secure_check_t secure_check,gc_realloc_t func_realloc,gc_free_t func_free)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)
110 {
111   gcry_set_allocation_handler (func_malloc, secure_malloc, secure_check,
112                                func_realloc, func_free);
113 }
114 
115 /* Ciphers. */
116 
117 Gc_rc
gc_cipher_open(Gc_cipher alg,Gc_cipher_mode mode,gc_cipher_handle * outhandle)118 gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode,
119                 gc_cipher_handle * outhandle)
120 {
121   int gcryalg, gcrymode;
122   gcry_error_t err;
123 
124   switch (alg)
125     {
126     case GC_AES128:
127       gcryalg = GCRY_CIPHER_RIJNDAEL;
128       break;
129 
130     case GC_AES192:
131       gcryalg = GCRY_CIPHER_RIJNDAEL;
132       break;
133 
134     case GC_AES256:
135       gcryalg = GCRY_CIPHER_RIJNDAEL256;
136       break;
137 
138     case GC_3DES:
139       gcryalg = GCRY_CIPHER_3DES;
140       break;
141 
142     case GC_DES:
143       gcryalg = GCRY_CIPHER_DES;
144       break;
145 
146     case GC_ARCFOUR128:
147     case GC_ARCFOUR40:
148       gcryalg = GCRY_CIPHER_ARCFOUR;
149       break;
150 
151     case GC_ARCTWO40:
152       gcryalg = GCRY_CIPHER_RFC2268_40;
153       break;
154 
155 #ifdef HAVE_CAMELLIA
156     case GC_CAMELLIA128:
157       gcryalg = GCRY_CIPHER_CAMELLIA128;
158       break;
159 
160     case GC_CAMELLIA256:
161       gcryalg = GCRY_CIPHER_CAMELLIA256;
162       break;
163 #endif
164 
165     default:
166       return GC_INVALID_CIPHER;
167     }
168 
169   switch (mode)
170     {
171     case GC_ECB:
172       gcrymode = GCRY_CIPHER_MODE_ECB;
173       break;
174 
175     case GC_CBC:
176       gcrymode = GCRY_CIPHER_MODE_CBC;
177       break;
178 
179     case GC_STREAM:
180       gcrymode = GCRY_CIPHER_MODE_STREAM;
181       break;
182 
183     default:
184       return GC_INVALID_CIPHER;
185     }
186 
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;
191 
192   return GC_OK;
193 }
194 
195 Gc_rc
gc_cipher_setkey(gc_cipher_handle handle,size_t keylen,const char * key)196 gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key)
197 {
198   gcry_error_t err;
199 
200   err = gcry_cipher_setkey ((gcry_cipher_hd_t) handle, key, keylen);
201   if (gcry_err_code (err))
202     return GC_INVALID_CIPHER;
203 
204   return GC_OK;
205 }
206 
207 Gc_rc
gc_cipher_setiv(gc_cipher_handle handle,size_t ivlen,const char * iv)208 gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv)
209 {
210   gcry_error_t err;
211 
212   err = gcry_cipher_setiv ((gcry_cipher_hd_t) handle, iv, ivlen);
213   if (gcry_err_code (err))
214     return GC_INVALID_CIPHER;
215 
216   return GC_OK;
217 }
218 
219 Gc_rc
gc_cipher_encrypt_inline(gc_cipher_handle handle,size_t len,char * data)220 gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data)
221 {
222   if (gcry_cipher_encrypt ((gcry_cipher_hd_t) handle,
223                            data, len, NULL, len) != 0)
224     return GC_INVALID_CIPHER;
225 
226   return GC_OK;
227 }
228 
229 Gc_rc
gc_cipher_decrypt_inline(gc_cipher_handle handle,size_t len,char * data)230 gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data)
231 {
232   if (gcry_cipher_decrypt ((gcry_cipher_hd_t) handle,
233                            data, len, NULL, len) != 0)
234     return GC_INVALID_CIPHER;
235 
236   return GC_OK;
237 }
238 
239 Gc_rc
gc_cipher_close(gc_cipher_handle handle)240 gc_cipher_close (gc_cipher_handle handle)
241 {
242   gcry_cipher_close (handle);
243 
244   return GC_OK;
245 }
246 
247 /* Hashes. */
248 
249 /* Maximum of GC_MD2_DIGEST_SIZE and GC_SM3_DIGEST_SIZE.  */
250 #define MAX_DIGEST_SIZE 32
251 
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;
266 
267 Gc_rc
gc_hash_open(Gc_hash hash,Gc_hash_mode mode,gc_hash_handle * outhandle)268 gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle)
269 {
270   _gc_hash_ctx *ctx;
271   int gcryalg = 0, gcrymode = 0;
272   gcry_error_t err;
273   Gc_rc rc = GC_OK;
274 
275   ctx = calloc (sizeof (*ctx), 1);
276   if (!ctx)
277     return GC_MALLOC_ERROR;
278 
279   ctx->alg = hash;
280   ctx->mode = mode;
281 
282   switch (hash)
283     {
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
291 
292     case GC_MD4:
293       gcryalg = GCRY_MD_MD4;
294       break;
295 
296     case GC_MD5:
297       gcryalg = GCRY_MD_MD5;
298       break;
299 
300     case GC_SHA1:
301       gcryalg = GCRY_MD_SHA1;
302       break;
303 
304     case GC_SHA256:
305       gcryalg = GCRY_MD_SHA256;
306       break;
307 
308     case GC_SHA384:
309       gcryalg = GCRY_MD_SHA384;
310       break;
311 
312     case GC_SHA512:
313       gcryalg = GCRY_MD_SHA512;
314       break;
315 
316     case GC_SHA224:
317       gcryalg = GCRY_MD_SHA224;
318       break;
319 
320     case GC_RMD160:
321       gcryalg = GCRY_MD_RMD160;
322       break;
323 
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
334 
335     default:
336       rc = GC_INVALID_HASH;
337     }
338 
339   switch (mode)
340     {
341     case GC_NULL:
342       gcrymode = 0;
343       break;
344 
345     case GC_HMAC:
346       gcrymode = GCRY_MD_FLAG_HMAC;
347       break;
348 
349     default:
350       rc = GC_INVALID_HASH;
351     }
352 
353   if (rc == GC_OK && gcryalg != GCRY_MD_NONE)
354     {
355       err = gcry_md_open (&ctx->gch, gcryalg, gcrymode);
356       if (gcry_err_code (err))
357         rc = GC_INVALID_HASH;
358     }
359 
360   if (rc == GC_OK)
361     *outhandle = ctx;
362   else
363     free (ctx);
364 
365   return rc;
366 }
367 
368 Gc_rc
gc_hash_clone(gc_hash_handle handle,gc_hash_handle * outhandle)369 gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle)
370 {
371   _gc_hash_ctx *in = handle;
372   _gc_hash_ctx *out;
373   int err;
374 
375   *outhandle = out = calloc (sizeof (*out), 1);
376   if (!out)
377     return GC_MALLOC_ERROR;
378 
379   memcpy (out, in, sizeof (*out));
380 
381   err = gcry_md_copy (&out->gch, in->gch);
382   if (err)
383     {
384       free (out);
385       return GC_INVALID_HASH;
386     }
387 
388   return GC_OK;
389 }
390 
391 size_t
gc_hash_digest_length(Gc_hash hash)392 gc_hash_digest_length (Gc_hash hash)
393 {
394   size_t len;
395 
396   switch (hash)
397     {
398     case GC_MD2:
399       len = GC_MD2_DIGEST_SIZE;
400       break;
401 
402     case GC_MD4:
403       len = GC_MD4_DIGEST_SIZE;
404       break;
405 
406     case GC_MD5:
407       len = GC_MD5_DIGEST_SIZE;
408       break;
409 
410     case GC_RMD160:
411       len = GC_RMD160_DIGEST_SIZE;
412       break;
413 
414     case GC_SHA1:
415       len = GC_SHA1_DIGEST_SIZE;
416       break;
417 
418     case GC_SHA256:
419       len = GC_SHA256_DIGEST_SIZE;
420       break;
421 
422     case GC_SHA384:
423       len = GC_SHA384_DIGEST_SIZE;
424       break;
425 
426     case GC_SHA512:
427       len = GC_SHA512_DIGEST_SIZE;
428       break;
429 
430     case GC_SHA224:
431       len = GC_SHA224_DIGEST_SIZE;
432       break;
433 
434     case GC_SM3:
435       len = GC_SM3_DIGEST_SIZE;
436       break;
437 
438     default:
439       return 0;
440     }
441 
442   return len;
443 }
444 
445 void
gc_hash_hmac_setkey(gc_hash_handle handle,size_t len,const char * key)446 gc_hash_hmac_setkey (gc_hash_handle handle, size_t len, const char *key)
447 {
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);
456 }
457 
458 void
gc_hash_write(gc_hash_handle handle,size_t len,const char * data)459 gc_hash_write (gc_hash_handle handle, size_t len, const char *data)
460 {
461   _gc_hash_ctx *ctx = handle;
462 
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);
474 }
475 
476 const char *
gc_hash_read(gc_hash_handle handle)477 gc_hash_read (gc_hash_handle handle)
478 {
479   _gc_hash_ctx *ctx = handle;
480   const char *digest;
481 
482 #if GNULIB_GC_MD2
483   if (ctx->alg == GC_MD2)
484     {
485       md2_finish_ctx (&ctx->md2Context, ctx->hash);
486       digest = ctx->hash;
487     }
488   else
489 #endif
490 #if GNULIB_GC_SM3 && !LIBGCRYPT_HAS_MD_SM3
491   if (ctx->alg == GC_SM3)
492     {
493       sm3_finish_ctx (&ctx->sm3Context, ctx->hash);
494       digest = ctx->hash;
495     }
496   else
497 #endif
498     {
499       gcry_md_final (ctx->gch);
500       digest = (const char *) gcry_md_read (ctx->gch, 0);
501     }
502 
503   return digest;
504 }
505 
506 void
gc_hash_close(gc_hash_handle handle)507 gc_hash_close (gc_hash_handle handle)
508 {
509   _gc_hash_ctx *ctx = handle;
510 
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);
518 
519   free (ctx);
520 }
521 
522 Gc_rc
gc_hash_buffer(Gc_hash hash,const void * in,size_t inlen,char * resbuf)523 gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf)
524 {
525   int gcryalg;
526 
527   switch (hash)
528     {
529 #if GNULIB_GC_MD2
530     case GC_MD2:
531       md2_buffer (in, inlen, resbuf);
532       return GC_OK;
533 #endif
534 
535 #if GNULIB_GC_MD4
536     case GC_MD4:
537       gcryalg = GCRY_MD_MD4;
538       break;
539 #endif
540 
541 #if GNULIB_GC_MD5
542     case GC_MD5:
543       gcryalg = GCRY_MD_MD5;
544       break;
545 #endif
546 
547 #if GNULIB_GC_SHA1
548     case GC_SHA1:
549       gcryalg = GCRY_MD_SHA1;
550       break;
551 #endif
552 
553 #if GNULIB_GC_SHA256
554     case GC_SHA256:
555       gcryalg = GCRY_MD_SHA256;
556       break;
557 #endif
558 
559 #if GNULIB_GC_SHA384
560     case GC_SHA384:
561       gcryalg = GCRY_MD_SHA384;
562       break;
563 #endif
564 
565 #if GNULIB_GC_SHA512
566     case GC_SHA512:
567       gcryalg = GCRY_MD_SHA512;
568       break;
569 #endif
570 
571 #if GNULIB_GC_SHA224
572     case GC_SHA224:
573       gcryalg = GCRY_MD_SHA224;
574       break;
575 #endif
576 
577 #if GNULIB_GC_RMD160
578     case GC_RMD160:
579       gcryalg = GCRY_MD_RMD160;
580       break;
581 #endif
582 
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
593 
594     default:
595       return GC_INVALID_HASH;
596     }
597 
598   gcry_md_hash_buffer (gcryalg, resbuf, in, inlen);
599 
600   return GC_OK;
601 }
602 
603 /* One-call interface. */
604 
605 #if GNULIB_GC_MD2
606 Gc_rc
gc_md2(const void * in,size_t inlen,void * resbuf)607 gc_md2 (const void *in, size_t inlen, void *resbuf)
608 {
609   md2_buffer (in, inlen, resbuf);
610   return GC_OK;
611 }
612 #endif
613 
614 #if GNULIB_GC_MD4
615 Gc_rc
gc_md4(const void * in,size_t inlen,void * resbuf)616 gc_md4 (const void *in, size_t inlen, void *resbuf)
617 {
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;
622 
623   assert (outlen == GC_MD4_DIGEST_SIZE);
624 
625   err = gcry_md_open (&hd, GCRY_MD_MD4, 0);
626   if (err != GPG_ERR_NO_ERROR)
627     return GC_INVALID_HASH;
628 
629   gcry_md_write (hd, in, inlen);
630 
631   p = gcry_md_read (hd, GCRY_MD_MD4);
632   if (p == NULL)
633     {
634       gcry_md_close (hd);
635       return GC_INVALID_HASH;
636     }
637 
638   memcpy (resbuf, p, outlen);
639 
640   gcry_md_close (hd);
641 
642   return GC_OK;
643 }
644 #endif
645 
646 #if GNULIB_GC_MD5
647 Gc_rc
gc_md5(const void * in,size_t inlen,void * resbuf)648 gc_md5 (const void *in, size_t inlen, void *resbuf)
649 {
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;
654 
655   assert (outlen == GC_MD5_DIGEST_SIZE);
656 
657   err = gcry_md_open (&hd, GCRY_MD_MD5, 0);
658   if (err != GPG_ERR_NO_ERROR)
659     return GC_INVALID_HASH;
660 
661   gcry_md_write (hd, in, inlen);
662 
663   p = gcry_md_read (hd, GCRY_MD_MD5);
664   if (p == NULL)
665     {
666       gcry_md_close (hd);
667       return GC_INVALID_HASH;
668     }
669 
670   memcpy (resbuf, p, outlen);
671 
672   gcry_md_close (hd);
673 
674   return GC_OK;
675 }
676 #endif
677 
678 #if GNULIB_GC_SHA1
679 Gc_rc
gc_sha1(const void * in,size_t inlen,void * resbuf)680 gc_sha1 (const void *in, size_t inlen, void *resbuf)
681 {
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;
686 
687   assert (outlen == GC_SHA1_DIGEST_SIZE);
688 
689   err = gcry_md_open (&hd, GCRY_MD_SHA1, 0);
690   if (err != GPG_ERR_NO_ERROR)
691     return GC_INVALID_HASH;
692 
693   gcry_md_write (hd, in, inlen);
694 
695   p = gcry_md_read (hd, GCRY_MD_SHA1);
696   if (p == NULL)
697     {
698       gcry_md_close (hd);
699       return GC_INVALID_HASH;
700     }
701 
702   memcpy (resbuf, p, outlen);
703 
704   gcry_md_close (hd);
705 
706   return GC_OK;
707 }
708 #endif
709 
710 #if GNULIB_GC_SHA256
711 Gc_rc
gc_sha256(const void * in,size_t inlen,void * resbuf)712 gc_sha256 (const void *in, size_t inlen, void *resbuf)
713 {
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;
718 
719   assert (outlen == GC_SHA256_DIGEST_SIZE);
720 
721   err = gcry_md_open (&hd, GCRY_MD_SHA256, 0);
722   if (err != GPG_ERR_NO_ERROR)
723     return GC_INVALID_HASH;
724 
725   gcry_md_write (hd, in, inlen);
726 
727   p = gcry_md_read (hd, GCRY_MD_SHA256);
728   if (p == NULL)
729     {
730       gcry_md_close (hd);
731       return GC_INVALID_HASH;
732     }
733 
734   memcpy (resbuf, p, outlen);
735 
736   gcry_md_close (hd);
737 
738   return GC_OK;
739 }
740 #endif
741 
742 #if GNULIB_GC_SHA512
743 Gc_rc
gc_sha512(const void * in,size_t inlen,void * resbuf)744 gc_sha512 (const void *in, size_t inlen, void *resbuf)
745 {
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;
750 
751   assert (outlen == GC_SHA512_DIGEST_SIZE);
752 
753   err = gcry_md_open (&hd, GCRY_MD_SHA512, 0);
754   if (err != GPG_ERR_NO_ERROR)
755     return GC_INVALID_HASH;
756 
757   gcry_md_write (hd, in, inlen);
758 
759   p = gcry_md_read (hd, GCRY_MD_SHA512);
760   if (p == NULL)
761     {
762       gcry_md_close (hd);
763       return GC_INVALID_HASH;
764     }
765 
766   memcpy (resbuf, p, outlen);
767 
768   gcry_md_close (hd);
769 
770   return GC_OK;
771 }
772 #endif
773 
774 #if GNULIB_GC_SM3
775 Gc_rc
gc_sm3(const void * in,size_t inlen,void * resbuf)776 gc_sm3  (const void *in, size_t inlen, void *resbuf)
777 {
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;
786 
787   assert (outlen == GC_SM3_DIGEST_SIZE);
788 
789   err = gcry_md_open (&hd, GCRY_MD_SM3, 0);
790   if (err != GPG_ERR_NO_ERROR)
791     return GC_INVALID_HASH;
792 
793   gcry_md_write (hd, in, inlen);
794 
795   p = gcry_md_read (hd, GCRY_MD_SM3);
796   if (p == NULL)
797     {
798       gcry_md_close (hd);
799       return GC_INVALID_HASH;
800     }
801 
802   memcpy (resbuf, p, outlen);
803 
804   gcry_md_close (hd);
805 
806   return GC_OK;
807 # endif
808 }
809 #endif
810 
811 #if GNULIB_GC_HMAC_MD5
812 Gc_rc
gc_hmac_md5(const void * key,size_t keylen,const void * in,size_t inlen,char * resbuf)813 gc_hmac_md5 (const void *key, size_t keylen,
814              const void *in, size_t inlen, char *resbuf)
815 {
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;
820 
821   assert (hlen == GC_MD5_DIGEST_SIZE);
822 
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;
826 
827   err = gcry_md_setkey (mdh, key, keylen);
828   if (err != GPG_ERR_NO_ERROR)
829     {
830       gcry_md_close (mdh);
831       return GC_INVALID_HASH;
832     }
833 
834   gcry_md_write (mdh, in, inlen);
835 
836   hash = gcry_md_read (mdh, GCRY_MD_MD5);
837   if (hash == NULL)
838     {
839       gcry_md_close (mdh);
840       return GC_INVALID_HASH;
841     }
842 
843   memcpy (resbuf, hash, hlen);
844 
845   gcry_md_close (mdh);
846 
847   return GC_OK;
848 }
849 #endif
850 
851 #if GNULIB_GC_HMAC_SHA1
852 Gc_rc
gc_hmac_sha1(const void * key,size_t keylen,const void * in,size_t inlen,char * resbuf)853 gc_hmac_sha1 (const void *key, size_t keylen,
854               const void *in, size_t inlen, char *resbuf)
855 {
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;
860 
861   assert (hlen == GC_SHA1_DIGEST_SIZE);
862 
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;
866 
867   err = gcry_md_setkey (mdh, key, keylen);
868   if (err != GPG_ERR_NO_ERROR)
869     {
870       gcry_md_close (mdh);
871       return GC_INVALID_HASH;
872     }
873 
874   gcry_md_write (mdh, in, inlen);
875 
876   hash = gcry_md_read (mdh, GCRY_MD_SHA1);
877   if (hash == NULL)
878     {
879       gcry_md_close (mdh);
880       return GC_INVALID_HASH;
881     }
882 
883   memcpy (resbuf, hash, hlen);
884 
885   gcry_md_close (mdh);
886 
887   return GC_OK;
888 }
889 #endif
890 
891 #if GNULIB_GC_HMAC_SHA256
892 Gc_rc
gc_hmac_sha256(const void * key,size_t keylen,const void * in,size_t inlen,char * resbuf)893 gc_hmac_sha256 (const void *key, size_t keylen,
894              const void *in, size_t inlen, char *resbuf)
895 {
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;
900 
901   assert (hlen == GC_SHA256_DIGEST_SIZE);
902 
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;
906 
907   err = gcry_md_setkey (mdh, key, keylen);
908   if (err != GPG_ERR_NO_ERROR)
909     {
910       gcry_md_close (mdh);
911       return GC_INVALID_HASH;
912     }
913 
914   gcry_md_write (mdh, in, inlen);
915 
916   hash = gcry_md_read (mdh, GCRY_MD_SHA256);
917   if (hash == NULL)
918     {
919       gcry_md_close (mdh);
920       return GC_INVALID_HASH;
921     }
922 
923   memcpy (resbuf, hash, hlen);
924 
925   gcry_md_close (mdh);
926 
927   return GC_OK;
928 }
929 #endif
930 
931 #if GNULIB_GC_HMAC_SHA512
932 Gc_rc
gc_hmac_sha512(const void * key,size_t keylen,const void * in,size_t inlen,char * resbuf)933 gc_hmac_sha512 (const void *key, size_t keylen,
934               const void *in, size_t inlen, char *resbuf)
935 {
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;
940 
941   assert (hlen == GC_SHA512_DIGEST_SIZE);
942 
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;
946 
947   err = gcry_md_setkey (mdh, key, keylen);
948   if (err != GPG_ERR_NO_ERROR)
949     {
950       gcry_md_close (mdh);
951       return GC_INVALID_HASH;
952     }
953 
954   gcry_md_write (mdh, in, inlen);
955 
956   hash = gcry_md_read (mdh, GCRY_MD_SHA512);
957   if (hash == NULL)
958     {
959       gcry_md_close (mdh);
960       return GC_INVALID_HASH;
961     }
962 
963   memcpy (resbuf, hash, hlen);
964 
965   gcry_md_close (mdh);
966 
967   return GC_OK;
968 }
969 #endif
970