pkgconfig: Fix libgcrypt.pc.
[libgcrypt.git] / cipher / mac.c
1 /* mac.c  -  message authentication code dispatcher
2  * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser general Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25
26 #include "g10lib.h"
27 #include "mac-internal.h"
28
29
30 /* This is the list of the digest implementations included in
31    libgcrypt.  */
32 static gcry_mac_spec_t * const mac_list[] = {
33 #if USE_SHA1
34   &_gcry_mac_type_spec_hmac_sha1,
35 #endif
36 #if USE_SHA256
37   &_gcry_mac_type_spec_hmac_sha256,
38   &_gcry_mac_type_spec_hmac_sha224,
39 #endif
40 #if USE_SHA512
41   &_gcry_mac_type_spec_hmac_sha512,
42   &_gcry_mac_type_spec_hmac_sha384,
43   &_gcry_mac_type_spec_hmac_sha512_256,
44   &_gcry_mac_type_spec_hmac_sha512_224,
45 #endif
46 #if USE_SHA3
47   &_gcry_mac_type_spec_hmac_sha3_224,
48   &_gcry_mac_type_spec_hmac_sha3_256,
49   &_gcry_mac_type_spec_hmac_sha3_384,
50   &_gcry_mac_type_spec_hmac_sha3_512,
51 #endif
52 #ifdef USE_GOST_R_3411_94
53   &_gcry_mac_type_spec_hmac_gost3411_94,
54   &_gcry_mac_type_spec_hmac_gost3411_cp,
55 #endif
56 #ifdef USE_GOST_R_3411_12
57   &_gcry_mac_type_spec_hmac_stribog256,
58   &_gcry_mac_type_spec_hmac_stribog512,
59 #endif
60 #if USE_WHIRLPOOL
61   &_gcry_mac_type_spec_hmac_whirlpool,
62 #endif
63 #if USE_RMD160
64   &_gcry_mac_type_spec_hmac_rmd160,
65 #endif
66 #if USE_TIGER
67   &_gcry_mac_type_spec_hmac_tiger1,
68 #endif
69 #if USE_MD5
70   &_gcry_mac_type_spec_hmac_md5,
71 #endif
72 #if USE_MD4
73   &_gcry_mac_type_spec_hmac_md4,
74 #endif
75 #if USE_BLAKE2
76   &_gcry_mac_type_spec_hmac_blake2b_512,
77   &_gcry_mac_type_spec_hmac_blake2b_384,
78   &_gcry_mac_type_spec_hmac_blake2b_256,
79   &_gcry_mac_type_spec_hmac_blake2b_160,
80   &_gcry_mac_type_spec_hmac_blake2s_256,
81   &_gcry_mac_type_spec_hmac_blake2s_224,
82   &_gcry_mac_type_spec_hmac_blake2s_160,
83   &_gcry_mac_type_spec_hmac_blake2s_128,
84 #endif
85 #if USE_SM3
86   &_gcry_mac_type_spec_hmac_sm3,
87 #endif
88 #if USE_BLOWFISH
89   &_gcry_mac_type_spec_cmac_blowfish,
90 #endif
91 #if USE_DES
92   &_gcry_mac_type_spec_cmac_tripledes,
93 #endif
94 #if USE_CAST5
95   &_gcry_mac_type_spec_cmac_cast5,
96 #endif
97 #if USE_AES
98   &_gcry_mac_type_spec_cmac_aes,
99   &_gcry_mac_type_spec_gmac_aes,
100   &_gcry_mac_type_spec_poly1305mac_aes,
101 #endif
102 #if USE_TWOFISH
103   &_gcry_mac_type_spec_cmac_twofish,
104   &_gcry_mac_type_spec_gmac_twofish,
105   &_gcry_mac_type_spec_poly1305mac_twofish,
106 #endif
107 #if USE_SERPENT
108   &_gcry_mac_type_spec_cmac_serpent,
109   &_gcry_mac_type_spec_gmac_serpent,
110   &_gcry_mac_type_spec_poly1305mac_serpent,
111 #endif
112 #if USE_RFC2268
113   &_gcry_mac_type_spec_cmac_rfc2268,
114 #endif
115 #if USE_SEED
116   &_gcry_mac_type_spec_cmac_seed,
117   &_gcry_mac_type_spec_gmac_seed,
118   &_gcry_mac_type_spec_poly1305mac_seed,
119 #endif
120 #if USE_CAMELLIA
121   &_gcry_mac_type_spec_cmac_camellia,
122   &_gcry_mac_type_spec_gmac_camellia,
123   &_gcry_mac_type_spec_poly1305mac_camellia,
124 #endif
125 #ifdef USE_IDEA
126   &_gcry_mac_type_spec_cmac_idea,
127 #endif
128 #if USE_GOST28147
129   &_gcry_mac_type_spec_cmac_gost28147,
130 #endif
131   &_gcry_mac_type_spec_poly1305mac,
132   NULL,
133 };
134
135 /* HMAC implementations start with index 101 (enum gcry_mac_algos) */
136 static gcry_mac_spec_t * const mac_list_algo101[] =
137   {
138 #if USE_SHA256
139     &_gcry_mac_type_spec_hmac_sha256,
140     &_gcry_mac_type_spec_hmac_sha224,
141 #else
142     NULL,
143     NULL,
144 #endif
145 #if USE_SHA512
146     &_gcry_mac_type_spec_hmac_sha512,
147     &_gcry_mac_type_spec_hmac_sha384,
148 #else
149     NULL,
150     NULL,
151 #endif
152 #if USE_SHA1
153     &_gcry_mac_type_spec_hmac_sha1,
154 #else
155     NULL,
156 #endif
157 #if USE_MD5
158     &_gcry_mac_type_spec_hmac_md5,
159 #else
160     NULL,
161 #endif
162 #if USE_MD4
163     &_gcry_mac_type_spec_hmac_md4,
164 #else
165     NULL,
166 #endif
167 #if USE_RMD160
168     &_gcry_mac_type_spec_hmac_rmd160,
169 #else
170     NULL,
171 #endif
172 #if USE_TIGER
173     &_gcry_mac_type_spec_hmac_tiger1,
174 #else
175     NULL,
176 #endif
177 #if USE_WHIRLPOOL
178     &_gcry_mac_type_spec_hmac_whirlpool,
179 #else
180     NULL,
181 #endif
182 #ifdef USE_GOST_R_3411_94
183     &_gcry_mac_type_spec_hmac_gost3411_94,
184 #else
185     NULL,
186 #endif
187 #ifdef USE_GOST_R_3411_12
188     &_gcry_mac_type_spec_hmac_stribog256,
189     &_gcry_mac_type_spec_hmac_stribog512,
190 #else
191     NULL,
192     NULL,
193 #endif
194 #if USE_MD2
195     &_gcry_mac_type_spec_hmac_md2,
196 #else
197     NULL,
198 #endif
199 #if USE_SHA3
200     &_gcry_mac_type_spec_hmac_sha3_224,
201     &_gcry_mac_type_spec_hmac_sha3_256,
202     &_gcry_mac_type_spec_hmac_sha3_384,
203     &_gcry_mac_type_spec_hmac_sha3_512,
204 #else
205     NULL,
206     NULL,
207     NULL,
208     NULL,
209 #endif
210 #ifdef USE_GOST_R_3411_94
211     &_gcry_mac_type_spec_hmac_gost3411_cp,
212 #else
213     NULL,
214 #endif
215 #if USE_BLAKE2
216     &_gcry_mac_type_spec_hmac_blake2b_512,
217     &_gcry_mac_type_spec_hmac_blake2b_384,
218     &_gcry_mac_type_spec_hmac_blake2b_256,
219     &_gcry_mac_type_spec_hmac_blake2b_160,
220     &_gcry_mac_type_spec_hmac_blake2s_256,
221     &_gcry_mac_type_spec_hmac_blake2s_224,
222     &_gcry_mac_type_spec_hmac_blake2s_160,
223     &_gcry_mac_type_spec_hmac_blake2s_128,
224 #else
225     NULL,
226     NULL,
227     NULL,
228     NULL,
229     NULL,
230     NULL,
231     NULL,
232     NULL,
233 #endif
234 #if USE_SM3
235     &_gcry_mac_type_spec_hmac_sm3,
236 #else
237     NULL,
238 #endif
239 #if USE_SHA512
240     &_gcry_mac_type_spec_hmac_sha512_256,
241     &_gcry_mac_type_spec_hmac_sha512_224,
242 #else
243     NULL,
244     NULL,
245 #endif
246   };
247
248 /* CMAC implementations start with index 201 (enum gcry_mac_algos) */
249 static gcry_mac_spec_t * const mac_list_algo201[] =
250   {
251 #if USE_AES
252     &_gcry_mac_type_spec_cmac_aes,
253 #else
254     NULL,
255 #endif
256 #if USE_DES
257     &_gcry_mac_type_spec_cmac_tripledes,
258 #else
259     NULL,
260 #endif
261 #if USE_CAMELLIA
262     &_gcry_mac_type_spec_cmac_camellia,
263 #else
264     NULL,
265 #endif
266 #if USE_CAST5
267     &_gcry_mac_type_spec_cmac_cast5,
268 #else
269     NULL,
270 #endif
271 #if USE_BLOWFISH
272     &_gcry_mac_type_spec_cmac_blowfish,
273 #else
274     NULL,
275 #endif
276 #if USE_TWOFISH
277     &_gcry_mac_type_spec_cmac_twofish,
278 #else
279     NULL,
280 #endif
281 #if USE_SERPENT
282     &_gcry_mac_type_spec_cmac_serpent,
283 #else
284     NULL,
285 #endif
286 #if USE_SEED
287     &_gcry_mac_type_spec_cmac_seed,
288 #else
289     NULL,
290 #endif
291 #if USE_RFC2268
292     &_gcry_mac_type_spec_cmac_rfc2268,
293 #else
294     NULL,
295 #endif
296 #ifdef USE_IDEA
297     &_gcry_mac_type_spec_cmac_idea,
298 #else
299     NULL,
300 #endif
301 #if USE_GOST28147
302     &_gcry_mac_type_spec_cmac_gost28147
303 #else
304     NULL
305 #endif
306   };
307
308 /* GMAC implementations start with index 401 (enum gcry_mac_algos) */
309 static gcry_mac_spec_t * const mac_list_algo401[] =
310   {
311 #if USE_AES
312     &_gcry_mac_type_spec_gmac_aes,
313 #else
314     NULL,
315 #endif
316 #if USE_CAMELLIA
317     &_gcry_mac_type_spec_gmac_camellia,
318 #else
319     NULL,
320 #endif
321 #if USE_TWOFISH
322     &_gcry_mac_type_spec_gmac_twofish,
323 #else
324     NULL,
325 #endif
326 #if USE_SERPENT
327     &_gcry_mac_type_spec_gmac_serpent,
328 #else
329     NULL,
330 #endif
331 #if USE_SEED
332     &_gcry_mac_type_spec_gmac_seed
333 #else
334     NULL
335 #endif
336   };
337
338 /* Poly1305-MAC implementations start with index 501 (enum gcry_mac_algos) */
339 static gcry_mac_spec_t * const mac_list_algo501[] =
340   {
341     &_gcry_mac_type_spec_poly1305mac,
342 #if USE_AES
343     &_gcry_mac_type_spec_poly1305mac_aes,
344 #else
345     NULL,
346 #endif
347 #if USE_CAMELLIA
348     &_gcry_mac_type_spec_poly1305mac_camellia,
349 #else
350     NULL,
351 #endif
352 #if USE_TWOFISH
353     &_gcry_mac_type_spec_poly1305mac_twofish,
354 #else
355     NULL,
356 #endif
357 #if USE_SERPENT
358     &_gcry_mac_type_spec_poly1305mac_serpent,
359 #else
360     NULL,
361 #endif
362 #if USE_SEED
363     &_gcry_mac_type_spec_poly1305mac_seed
364 #else
365     NULL
366 #endif
367   };
368
369
370
371
372 /* Explicitly initialize this module.  */
373 gcry_err_code_t
374 _gcry_mac_init (void)
375 {
376   if (fips_mode())
377     {
378       /* disable algorithms that are disallowed in fips */
379       int idx;
380       gcry_mac_spec_t *spec;
381
382       for (idx = 0; (spec = mac_list[idx]); idx++)
383         if (!spec->flags.fips)
384           spec->flags.disabled = 1;
385     }
386
387   return 0;
388 }
389
390 \f
391 /* Return the spec structure for the MAC algorithm ALGO.  For an
392    unknown algorithm NULL is returned.  */
393 static gcry_mac_spec_t *
394 spec_from_algo (int algo)
395 {
396   gcry_mac_spec_t *spec = NULL;
397
398   if (algo >= 101 && algo < 101 + DIM(mac_list_algo101))
399     spec = mac_list_algo101[algo - 101];
400   else if (algo >= 201 && algo < 201 + DIM(mac_list_algo201))
401     spec = mac_list_algo201[algo - 201];
402   else if (algo >= 401 && algo < 401 + DIM(mac_list_algo401))
403     spec = mac_list_algo401[algo - 401];
404   else if (algo >= 501 && algo < 501 + DIM(mac_list_algo501))
405     spec = mac_list_algo501[algo - 501];
406
407   if (spec)
408     gcry_assert (spec->algo == algo);
409
410   return spec;
411 }
412
413
414 /* Lookup a mac's spec by its name.  */
415 static gcry_mac_spec_t *
416 spec_from_name (const char *name)
417 {
418   gcry_mac_spec_t *spec;
419   int idx;
420
421   for (idx = 0; (spec = mac_list[idx]); idx++)
422     if (!stricmp (name, spec->name))
423       return spec;
424
425   return NULL;
426 }
427
428
429 /****************
430  * Map a string to the mac algo
431  */
432 int
433 _gcry_mac_map_name (const char *string)
434 {
435   gcry_mac_spec_t *spec;
436
437   if (!string)
438     return 0;
439
440   /* Not found, search a matching mac name.  */
441   spec = spec_from_name (string);
442   if (spec)
443     return spec->algo;
444
445   return 0;
446 }
447
448
449 /****************
450  * This function simply returns the name of the algorithm or some constant
451  * string when there is no algo.  It will never return NULL.
452  * Use the macro gcry_mac_test_algo() to check whether the algorithm
453  * is valid.
454  */
455 const char *
456 _gcry_mac_algo_name (int algorithm)
457 {
458   gcry_mac_spec_t *spec;
459
460   spec = spec_from_algo (algorithm);
461   return spec ? spec->name : "?";
462 }
463
464
465 static gcry_err_code_t
466 check_mac_algo (int algorithm)
467 {
468   gcry_mac_spec_t *spec;
469
470   spec = spec_from_algo (algorithm);
471   if (spec && !spec->flags.disabled)
472     return 0;
473
474   return GPG_ERR_MAC_ALGO;
475 }
476
477
478 /****************
479  * Open a message digest handle for use with algorithm ALGO.
480  */
481 static gcry_err_code_t
482 mac_open (gcry_mac_hd_t * hd, int algo, int secure, gcry_ctx_t ctx)
483 {
484   gcry_mac_spec_t *spec;
485   gcry_err_code_t err;
486   gcry_mac_hd_t h;
487
488   spec = spec_from_algo (algo);
489   if (!spec)
490     return GPG_ERR_MAC_ALGO;
491   else if (spec->flags.disabled)
492     return GPG_ERR_MAC_ALGO;
493   else if (!spec->ops)
494     return GPG_ERR_MAC_ALGO;
495   else if (!spec->ops->open || !spec->ops->write || !spec->ops->setkey ||
496            !spec->ops->read || !spec->ops->verify || !spec->ops->reset)
497     return GPG_ERR_MAC_ALGO;
498
499   if (secure)
500     h = xtrycalloc_secure (1, sizeof (*h));
501   else
502     h = xtrycalloc (1, sizeof (*h));
503
504   if (!h)
505     return gpg_err_code_from_syserror ();
506
507   h->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
508   h->spec = spec;
509   h->algo = algo;
510   h->gcry_ctx = ctx;
511
512   err = h->spec->ops->open (h);
513   if (err)
514     xfree (h);
515   else
516     *hd = h;
517
518   return err;
519 }
520
521
522 static gcry_err_code_t
523 mac_reset (gcry_mac_hd_t hd)
524 {
525   if (hd->spec->ops->reset)
526     return hd->spec->ops->reset (hd);
527
528   return 0;
529 }
530
531
532 static void
533 mac_close (gcry_mac_hd_t hd)
534 {
535   if (hd->spec->ops->close)
536     hd->spec->ops->close (hd);
537
538   wipememory (hd, sizeof (*hd));
539
540   xfree (hd);
541 }
542
543
544 static gcry_err_code_t
545 mac_setkey (gcry_mac_hd_t hd, const void *key, size_t keylen)
546 {
547   if (!hd->spec->ops->setkey)
548     return GPG_ERR_INV_ARG;
549   if (keylen > 0 && !key)
550     return GPG_ERR_INV_ARG;
551
552   return hd->spec->ops->setkey (hd, key, keylen);
553 }
554
555
556 static gcry_err_code_t
557 mac_setiv (gcry_mac_hd_t hd, const void *iv, size_t ivlen)
558 {
559   if (!hd->spec->ops->setiv)
560     return GPG_ERR_INV_ARG;
561   if (ivlen > 0 && !iv)
562     return GPG_ERR_INV_ARG;
563
564   return hd->spec->ops->setiv (hd, iv, ivlen);
565 }
566
567
568 static gcry_err_code_t
569 mac_write (gcry_mac_hd_t hd, const void *inbuf, size_t inlen)
570 {
571   if (!hd->spec->ops->write)
572     return GPG_ERR_INV_ARG;
573   if (inlen > 0 && !inbuf)
574     return GPG_ERR_INV_ARG;
575
576   return hd->spec->ops->write (hd, inbuf, inlen);
577 }
578
579
580 static gcry_err_code_t
581 mac_read (gcry_mac_hd_t hd, void *outbuf, size_t * outlen)
582 {
583   if (!outbuf || !outlen || *outlen == 0 || !hd->spec->ops->read)
584     return GPG_ERR_INV_ARG;
585
586   return hd->spec->ops->read (hd, outbuf, outlen);
587 }
588
589
590 static gcry_err_code_t
591 mac_verify (gcry_mac_hd_t hd, const void *buf, size_t buflen)
592 {
593   if (!buf || buflen == 0 || !hd->spec->ops->verify)
594     return GPG_ERR_INV_ARG;
595
596   return hd->spec->ops->verify (hd, buf, buflen);
597 }
598
599
600 /* Create a MAC object for algorithm ALGO.  FLAGS may be
601    given as an bitwise OR of the gcry_mac_flags values.
602    H is guaranteed to be a valid handle or NULL on error.  */
603 gpg_err_code_t
604 _gcry_mac_open (gcry_mac_hd_t * h, int algo, unsigned int flags,
605                 gcry_ctx_t ctx)
606 {
607   gcry_err_code_t rc;
608   gcry_mac_hd_t hd = NULL;
609
610   if ((flags & ~GCRY_MAC_FLAG_SECURE))
611     rc = GPG_ERR_INV_ARG;
612   else
613     rc = mac_open (&hd, algo, !!(flags & GCRY_MAC_FLAG_SECURE), ctx);
614
615   *h = rc ? NULL : hd;
616   return rc;
617 }
618
619
620 void
621 _gcry_mac_close (gcry_mac_hd_t hd)
622 {
623   if (hd)
624     mac_close (hd);
625 }
626
627
628 gcry_err_code_t
629 _gcry_mac_setkey (gcry_mac_hd_t hd, const void *key, size_t keylen)
630 {
631   return mac_setkey (hd, key, keylen);
632 }
633
634
635 gcry_err_code_t
636 _gcry_mac_setiv (gcry_mac_hd_t hd, const void *iv, size_t ivlen)
637 {
638   return mac_setiv (hd, iv, ivlen);
639 }
640
641
642 gcry_err_code_t
643 _gcry_mac_write (gcry_mac_hd_t hd, const void *inbuf, size_t inlen)
644 {
645   return mac_write (hd, inbuf, inlen);
646 }
647
648
649 gcry_err_code_t
650 _gcry_mac_read (gcry_mac_hd_t hd, void *outbuf, size_t * outlen)
651 {
652   return mac_read (hd, outbuf, outlen);
653 }
654
655
656 gcry_err_code_t
657 _gcry_mac_verify (gcry_mac_hd_t hd, const void *buf, size_t buflen)
658 {
659   return mac_verify (hd, buf, buflen);
660 }
661
662
663 int
664 _gcry_mac_get_algo (gcry_mac_hd_t hd)
665 {
666   return hd->algo;
667 }
668
669
670 unsigned int
671 _gcry_mac_get_algo_maclen (int algo)
672 {
673   gcry_mac_spec_t *spec;
674
675   spec = spec_from_algo (algo);
676   if (!spec || !spec->ops || !spec->ops->get_maclen)
677     return 0;
678
679   return spec->ops->get_maclen (algo);
680 }
681
682
683 unsigned int
684 _gcry_mac_get_algo_keylen (int algo)
685 {
686   gcry_mac_spec_t *spec;
687
688   spec = spec_from_algo (algo);
689   if (!spec || !spec->ops || !spec->ops->get_keylen)
690     return 0;
691
692   return spec->ops->get_keylen (algo);
693 }
694
695
696 gcry_err_code_t
697 _gcry_mac_ctl (gcry_mac_hd_t hd, int cmd, void *buffer, size_t buflen)
698 {
699   gcry_err_code_t rc;
700
701   /* Currently not used.  */
702   (void) hd;
703   (void) buffer;
704   (void) buflen;
705
706   switch (cmd)
707     {
708     case GCRYCTL_RESET:
709       rc = mac_reset (hd);
710       break;
711     default:
712       rc = GPG_ERR_INV_OP;
713     }
714   return rc;
715 }
716
717
718 /* Return information about the given MAC algorithm ALGO.
719
720     GCRYCTL_TEST_ALGO:
721         Returns 0 if the specified algorithm ALGO is available for use.
722         BUFFER and NBYTES must be zero.
723
724    Note: Because this function is in most cases used to return an
725    integer value, we can make it easier for the caller to just look at
726    the return value.  The caller will in all cases consult the value
727    and thereby detecting whether a error occurred or not (i.e. while
728    checking the block size)
729  */
730 gcry_err_code_t
731 _gcry_mac_algo_info (int algo, int what, void *buffer, size_t * nbytes)
732 {
733   gcry_err_code_t rc = 0;
734   unsigned int ui;
735
736   switch (what)
737     {
738     case GCRYCTL_GET_KEYLEN:
739       if (buffer || (!nbytes))
740         rc = GPG_ERR_INV_ARG;
741       else
742         {
743           ui = _gcry_mac_get_algo_keylen (algo);
744           if (ui > 0)
745             *nbytes = (size_t) ui;
746           else
747             /* The only reason for an error is an invalid algo.  */
748             rc = GPG_ERR_MAC_ALGO;
749         }
750       break;
751     case GCRYCTL_TEST_ALGO:
752       if (buffer || nbytes)
753         rc = GPG_ERR_INV_ARG;
754       else
755         rc = check_mac_algo (algo);
756       break;
757
758     default:
759       rc = GPG_ERR_INV_OP;
760     }
761
762   return rc;
763 }