LCOV - code coverage report
Current view: top level - cipher - mac.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 147 0.0 %
Date: 2016-12-15 12:59:22 Functions: 0 26 0.0 %

          Line data    Source code
       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 *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             : #endif
      44             : #if USE_SHA3
      45             :   &_gcry_mac_type_spec_hmac_sha3_224,
      46             :   &_gcry_mac_type_spec_hmac_sha3_256,
      47             :   &_gcry_mac_type_spec_hmac_sha3_384,
      48             :   &_gcry_mac_type_spec_hmac_sha3_512,
      49             : #endif
      50             : #ifdef USE_GOST_R_3411_94
      51             :   &_gcry_mac_type_spec_hmac_gost3411_94,
      52             : #endif
      53             : #ifdef USE_GOST_R_3411_12
      54             :   &_gcry_mac_type_spec_hmac_stribog256,
      55             :   &_gcry_mac_type_spec_hmac_stribog512,
      56             : #endif
      57             : #if USE_WHIRLPOOL
      58             :   &_gcry_mac_type_spec_hmac_whirlpool,
      59             : #endif
      60             : #if USE_RMD160
      61             :   &_gcry_mac_type_spec_hmac_rmd160,
      62             : #endif
      63             : #if USE_TIGER
      64             :   &_gcry_mac_type_spec_hmac_tiger1,
      65             : #endif
      66             : #if USE_MD5
      67             :   &_gcry_mac_type_spec_hmac_md5,
      68             : #endif
      69             : #if USE_MD4
      70             :   &_gcry_mac_type_spec_hmac_md4,
      71             : #endif
      72             : #if USE_BLOWFISH
      73             :   &_gcry_mac_type_spec_cmac_blowfish,
      74             : #endif
      75             : #if USE_DES
      76             :   &_gcry_mac_type_spec_cmac_tripledes,
      77             : #endif
      78             : #if USE_CAST5
      79             :   &_gcry_mac_type_spec_cmac_cast5,
      80             : #endif
      81             : #if USE_AES
      82             :   &_gcry_mac_type_spec_cmac_aes,
      83             :   &_gcry_mac_type_spec_gmac_aes,
      84             :   &_gcry_mac_type_spec_poly1305mac_aes,
      85             : #endif
      86             : #if USE_TWOFISH
      87             :   &_gcry_mac_type_spec_cmac_twofish,
      88             :   &_gcry_mac_type_spec_gmac_twofish,
      89             :   &_gcry_mac_type_spec_poly1305mac_twofish,
      90             : #endif
      91             : #if USE_SERPENT
      92             :   &_gcry_mac_type_spec_cmac_serpent,
      93             :   &_gcry_mac_type_spec_gmac_serpent,
      94             :   &_gcry_mac_type_spec_poly1305mac_serpent,
      95             : #endif
      96             : #if USE_RFC2268
      97             :   &_gcry_mac_type_spec_cmac_rfc2268,
      98             : #endif
      99             : #if USE_SEED
     100             :   &_gcry_mac_type_spec_cmac_seed,
     101             :   &_gcry_mac_type_spec_gmac_seed,
     102             :   &_gcry_mac_type_spec_poly1305mac_seed,
     103             : #endif
     104             : #if USE_CAMELLIA
     105             :   &_gcry_mac_type_spec_cmac_camellia,
     106             :   &_gcry_mac_type_spec_gmac_camellia,
     107             :   &_gcry_mac_type_spec_poly1305mac_camellia,
     108             : #endif
     109             : #ifdef USE_IDEA
     110             :   &_gcry_mac_type_spec_cmac_idea,
     111             : #endif
     112             : #if USE_GOST28147
     113             :   &_gcry_mac_type_spec_cmac_gost28147,
     114             : #endif
     115             :   &_gcry_mac_type_spec_poly1305mac,
     116             :   NULL,
     117             : };
     118             : 
     119             : /* Explicitly initialize this module.  */
     120             : gcry_err_code_t
     121           0 : _gcry_mac_init (void)
     122             : {
     123           0 :   if (fips_mode())
     124             :     {
     125             :       /* disable algorithms that are disallowed in fips */
     126             :       int idx;
     127             :       gcry_mac_spec_t *spec;
     128             : 
     129           0 :       for (idx = 0; (spec = mac_list[idx]); idx++)
     130           0 :         if (!spec->flags.fips)
     131           0 :           spec->flags.disabled = 1;
     132             :     }
     133             : 
     134           0 :   return 0;
     135             : }
     136             : 
     137             : 
     138             : /* Return the spec structure for the MAC algorithm ALGO.  For an
     139             :    unknown algorithm NULL is returned.  */
     140             : static gcry_mac_spec_t *
     141           0 : spec_from_algo (int algo)
     142             : {
     143             :   gcry_mac_spec_t *spec;
     144             :   int idx;
     145             : 
     146           0 :   for (idx = 0; (spec = mac_list[idx]); idx++)
     147           0 :     if (algo == spec->algo)
     148           0 :       return spec;
     149           0 :   return NULL;
     150             : }
     151             : 
     152             : 
     153             : /* Lookup a mac's spec by its name.  */
     154             : static gcry_mac_spec_t *
     155           0 : spec_from_name (const char *name)
     156             : {
     157             :   gcry_mac_spec_t *spec;
     158             :   int idx;
     159             : 
     160           0 :   for (idx = 0; (spec = mac_list[idx]); idx++)
     161           0 :     if (!stricmp (name, spec->name))
     162           0 :       return spec;
     163             : 
     164           0 :   return NULL;
     165             : }
     166             : 
     167             : 
     168             : /****************
     169             :  * Map a string to the mac algo
     170             :  */
     171             : int
     172           0 : _gcry_mac_map_name (const char *string)
     173             : {
     174             :   gcry_mac_spec_t *spec;
     175             : 
     176           0 :   if (!string)
     177           0 :     return 0;
     178             : 
     179             :   /* Not found, search a matching mac name.  */
     180           0 :   spec = spec_from_name (string);
     181           0 :   if (spec)
     182           0 :     return spec->algo;
     183             : 
     184           0 :   return 0;
     185             : }
     186             : 
     187             : 
     188             : /****************
     189             :  * This function simply returns the name of the algorithm or some constant
     190             :  * string when there is no algo.  It will never return NULL.
     191             :  * Use the macro gcry_mac_test_algo() to check whether the algorithm
     192             :  * is valid.
     193             :  */
     194             : const char *
     195           0 : _gcry_mac_algo_name (int algorithm)
     196             : {
     197             :   gcry_mac_spec_t *spec;
     198             : 
     199           0 :   spec = spec_from_algo (algorithm);
     200           0 :   return spec ? spec->name : "?";
     201             : }
     202             : 
     203             : 
     204             : static gcry_err_code_t
     205           0 : check_mac_algo (int algorithm)
     206             : {
     207             :   gcry_mac_spec_t *spec;
     208             : 
     209           0 :   spec = spec_from_algo (algorithm);
     210           0 :   if (spec && !spec->flags.disabled)
     211           0 :     return 0;
     212             : 
     213           0 :   return GPG_ERR_MAC_ALGO;
     214             : }
     215             : 
     216             : 
     217             : /****************
     218             :  * Open a message digest handle for use with algorithm ALGO.
     219             :  */
     220             : static gcry_err_code_t
     221           0 : mac_open (gcry_mac_hd_t * hd, int algo, int secure, gcry_ctx_t ctx)
     222             : {
     223             :   gcry_mac_spec_t *spec;
     224             :   gcry_err_code_t err;
     225             :   gcry_mac_hd_t h;
     226             : 
     227           0 :   spec = spec_from_algo (algo);
     228           0 :   if (!spec)
     229           0 :     return GPG_ERR_MAC_ALGO;
     230           0 :   else if (spec->flags.disabled)
     231           0 :     return GPG_ERR_MAC_ALGO;
     232           0 :   else if (!spec->ops)
     233           0 :     return GPG_ERR_MAC_ALGO;
     234           0 :   else if (!spec->ops->open || !spec->ops->write || !spec->ops->setkey ||
     235           0 :            !spec->ops->read || !spec->ops->verify || !spec->ops->reset)
     236           0 :     return GPG_ERR_MAC_ALGO;
     237             : 
     238           0 :   if (secure)
     239           0 :     h = xtrycalloc_secure (1, sizeof (*h));
     240             :   else
     241           0 :     h = xtrycalloc (1, sizeof (*h));
     242             : 
     243           0 :   if (!h)
     244           0 :     return gpg_err_code_from_syserror ();
     245             : 
     246           0 :   h->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
     247           0 :   h->spec = spec;
     248           0 :   h->algo = algo;
     249           0 :   h->gcry_ctx = ctx;
     250             : 
     251           0 :   err = h->spec->ops->open (h);
     252           0 :   if (err)
     253           0 :     xfree (h);
     254             :   else
     255           0 :     *hd = h;
     256             : 
     257           0 :   return err;
     258             : }
     259             : 
     260             : 
     261             : static gcry_err_code_t
     262           0 : mac_reset (gcry_mac_hd_t hd)
     263             : {
     264           0 :   if (hd->spec->ops->reset)
     265           0 :     return hd->spec->ops->reset (hd);
     266             : 
     267           0 :   return 0;
     268             : }
     269             : 
     270             : 
     271             : static void
     272           0 : mac_close (gcry_mac_hd_t hd)
     273             : {
     274           0 :   if (hd->spec->ops->close)
     275           0 :     hd->spec->ops->close (hd);
     276             : 
     277           0 :   wipememory (hd, sizeof (*hd));
     278             : 
     279           0 :   xfree (hd);
     280           0 : }
     281             : 
     282             : 
     283             : static gcry_err_code_t
     284           0 : mac_setkey (gcry_mac_hd_t hd, const void *key, size_t keylen)
     285             : {
     286           0 :   if (!hd->spec->ops->setkey)
     287           0 :     return GPG_ERR_INV_ARG;
     288           0 :   if (keylen > 0 && !key)
     289           0 :     return GPG_ERR_INV_ARG;
     290             : 
     291           0 :   return hd->spec->ops->setkey (hd, key, keylen);
     292             : }
     293             : 
     294             : 
     295             : static gcry_err_code_t
     296           0 : mac_setiv (gcry_mac_hd_t hd, const void *iv, size_t ivlen)
     297             : {
     298           0 :   if (!hd->spec->ops->setiv)
     299           0 :     return GPG_ERR_INV_ARG;
     300           0 :   if (ivlen > 0 && !iv)
     301           0 :     return GPG_ERR_INV_ARG;
     302             : 
     303           0 :   return hd->spec->ops->setiv (hd, iv, ivlen);
     304             : }
     305             : 
     306             : 
     307             : static gcry_err_code_t
     308           0 : mac_write (gcry_mac_hd_t hd, const void *inbuf, size_t inlen)
     309             : {
     310           0 :   if (!hd->spec->ops->write)
     311           0 :     return GPG_ERR_INV_ARG;
     312           0 :   if (inlen > 0 && !inbuf)
     313           0 :     return GPG_ERR_INV_ARG;
     314             : 
     315           0 :   return hd->spec->ops->write (hd, inbuf, inlen);
     316             : }
     317             : 
     318             : 
     319             : static gcry_err_code_t
     320           0 : mac_read (gcry_mac_hd_t hd, void *outbuf, size_t * outlen)
     321             : {
     322           0 :   if (!outbuf || !outlen || *outlen == 0 || !hd->spec->ops->read)
     323           0 :     return GPG_ERR_INV_ARG;
     324             : 
     325           0 :   return hd->spec->ops->read (hd, outbuf, outlen);
     326             : }
     327             : 
     328             : 
     329             : static gcry_err_code_t
     330           0 : mac_verify (gcry_mac_hd_t hd, const void *buf, size_t buflen)
     331             : {
     332           0 :   if (!buf || buflen == 0 || !hd->spec->ops->verify)
     333           0 :     return GPG_ERR_INV_ARG;
     334             : 
     335           0 :   return hd->spec->ops->verify (hd, buf, buflen);
     336             : }
     337             : 
     338             : 
     339             : /* Create a MAC object for algorithm ALGO.  FLAGS may be
     340             :    given as an bitwise OR of the gcry_mac_flags values.
     341             :    H is guaranteed to be a valid handle or NULL on error.  */
     342             : gpg_err_code_t
     343           0 : _gcry_mac_open (gcry_mac_hd_t * h, int algo, unsigned int flags,
     344             :                 gcry_ctx_t ctx)
     345             : {
     346             :   gcry_err_code_t rc;
     347           0 :   gcry_mac_hd_t hd = NULL;
     348             : 
     349           0 :   if ((flags & ~GCRY_MAC_FLAG_SECURE))
     350           0 :     rc = GPG_ERR_INV_ARG;
     351             :   else
     352           0 :     rc = mac_open (&hd, algo, !!(flags & GCRY_MAC_FLAG_SECURE), ctx);
     353             : 
     354           0 :   *h = rc ? NULL : hd;
     355           0 :   return rc;
     356             : }
     357             : 
     358             : 
     359             : void
     360           0 : _gcry_mac_close (gcry_mac_hd_t hd)
     361             : {
     362           0 :   if (hd)
     363           0 :     mac_close (hd);
     364           0 : }
     365             : 
     366             : 
     367             : gcry_err_code_t
     368           0 : _gcry_mac_setkey (gcry_mac_hd_t hd, const void *key, size_t keylen)
     369             : {
     370           0 :   return mac_setkey (hd, key, keylen);
     371             : }
     372             : 
     373             : 
     374             : gcry_err_code_t
     375           0 : _gcry_mac_setiv (gcry_mac_hd_t hd, const void *iv, size_t ivlen)
     376             : {
     377           0 :   return mac_setiv (hd, iv, ivlen);
     378             : }
     379             : 
     380             : 
     381             : gcry_err_code_t
     382           0 : _gcry_mac_write (gcry_mac_hd_t hd, const void *inbuf, size_t inlen)
     383             : {
     384           0 :   return mac_write (hd, inbuf, inlen);
     385             : }
     386             : 
     387             : 
     388             : gcry_err_code_t
     389           0 : _gcry_mac_read (gcry_mac_hd_t hd, void *outbuf, size_t * outlen)
     390             : {
     391           0 :   return mac_read (hd, outbuf, outlen);
     392             : }
     393             : 
     394             : 
     395             : gcry_err_code_t
     396           0 : _gcry_mac_verify (gcry_mac_hd_t hd, const void *buf, size_t buflen)
     397             : {
     398           0 :   return mac_verify (hd, buf, buflen);
     399             : }
     400             : 
     401             : 
     402             : int
     403           0 : _gcry_mac_get_algo (gcry_mac_hd_t hd)
     404             : {
     405           0 :   return hd->algo;
     406             : }
     407             : 
     408             : 
     409             : unsigned int
     410           0 : _gcry_mac_get_algo_maclen (int algo)
     411             : {
     412             :   gcry_mac_spec_t *spec;
     413             : 
     414           0 :   spec = spec_from_algo (algo);
     415           0 :   if (!spec || !spec->ops || !spec->ops->get_maclen)
     416           0 :     return 0;
     417             : 
     418           0 :   return spec->ops->get_maclen (algo);
     419             : }
     420             : 
     421             : 
     422             : unsigned int
     423           0 : _gcry_mac_get_algo_keylen (int algo)
     424             : {
     425             :   gcry_mac_spec_t *spec;
     426             : 
     427           0 :   spec = spec_from_algo (algo);
     428           0 :   if (!spec || !spec->ops || !spec->ops->get_keylen)
     429           0 :     return 0;
     430             : 
     431           0 :   return spec->ops->get_keylen (algo);
     432             : }
     433             : 
     434             : 
     435             : gcry_err_code_t
     436           0 : _gcry_mac_ctl (gcry_mac_hd_t hd, int cmd, void *buffer, size_t buflen)
     437             : {
     438             :   gcry_err_code_t rc;
     439             : 
     440             :   /* Currently not used.  */
     441             :   (void) hd;
     442             :   (void) buffer;
     443             :   (void) buflen;
     444             : 
     445           0 :   switch (cmd)
     446             :     {
     447             :     case GCRYCTL_RESET:
     448           0 :       rc = mac_reset (hd);
     449           0 :       break;
     450             :     default:
     451           0 :       rc = GPG_ERR_INV_OP;
     452             :     }
     453           0 :   return rc;
     454             : }
     455             : 
     456             : 
     457             : /* Return information about the given MAC algorithm ALGO.
     458             : 
     459             :     GCRYCTL_TEST_ALGO:
     460             :         Returns 0 if the specified algorithm ALGO is available for use.
     461             :         BUFFER and NBYTES must be zero.
     462             : 
     463             :    Note: Because this function is in most cases used to return an
     464             :    integer value, we can make it easier for the caller to just look at
     465             :    the return value.  The caller will in all cases consult the value
     466             :    and thereby detecting whether a error occurred or not (i.e. while
     467             :    checking the block size)
     468             :  */
     469             : gcry_err_code_t
     470           0 : _gcry_mac_algo_info (int algo, int what, void *buffer, size_t * nbytes)
     471             : {
     472           0 :   gcry_err_code_t rc = 0;
     473             :   unsigned int ui;
     474             : 
     475           0 :   switch (what)
     476             :     {
     477             :     case GCRYCTL_GET_KEYLEN:
     478           0 :       if (buffer || (!nbytes))
     479           0 :         rc = GPG_ERR_INV_ARG;
     480             :       else
     481             :         {
     482           0 :           ui = _gcry_mac_get_algo_keylen (algo);
     483           0 :           if (ui > 0)
     484           0 :             *nbytes = (size_t) ui;
     485             :           else
     486             :             /* The only reason for an error is an invalid algo.  */
     487           0 :             rc = GPG_ERR_MAC_ALGO;
     488             :         }
     489           0 :       break;
     490             :     case GCRYCTL_TEST_ALGO:
     491           0 :       if (buffer || nbytes)
     492           0 :         rc = GPG_ERR_INV_ARG;
     493             :       else
     494           0 :         rc = check_mac_algo (algo);
     495           0 :       break;
     496             : 
     497             :     default:
     498           0 :       rc = GPG_ERR_INV_OP;
     499             :     }
     500             : 
     501           0 :   return rc;
     502             : }

Generated by: LCOV version 1.12