LCOV - code coverage report
Current view: top level - cipher - md.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 376 533 70.5 %
Date: 2017-03-02 16:44:37 Functions: 35 45 77.8 %

          Line data    Source code
       1             : /* md.c  -  message digest dispatcher
       2             :  * Copyright (C) 1998, 1999, 2002, 2003, 2006,
       3             :  *               2008 Free Software Foundation, Inc.
       4             :  * Copyright (C) 2013, 2014 g10 Code GmbH
       5             :  *
       6             :  * This file is part of Libgcrypt.
       7             :  *
       8             :  * Libgcrypt is free software; you can redistribute it and/or modify
       9             :  * it under the terms of the GNU Lesser general Public License as
      10             :  * published by the Free Software Foundation; either version 2.1 of
      11             :  * the License, or (at your option) any later version.
      12             :  *
      13             :  * Libgcrypt is distributed in the hope that it will be useful,
      14             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :  * GNU Lesser General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU Lesser General Public
      19             :  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
      20             :  */
      21             : 
      22             : #include <config.h>
      23             : #include <stdio.h>
      24             : #include <stdlib.h>
      25             : #include <string.h>
      26             : #include <errno.h>
      27             : 
      28             : #include "g10lib.h"
      29             : #include "cipher.h"
      30             : 
      31             : 
      32             : /* This is the list of the digest implementations included in
      33             :    libgcrypt.  */
      34             : static gcry_md_spec_t *digest_list[] =
      35             :   {
      36             : #if USE_CRC
      37             :      &_gcry_digest_spec_crc32,
      38             :      &_gcry_digest_spec_crc32_rfc1510,
      39             :      &_gcry_digest_spec_crc24_rfc2440,
      40             : #endif
      41             : #if USE_SHA1
      42             :      &_gcry_digest_spec_sha1,
      43             : #endif
      44             : #if USE_SHA256
      45             :      &_gcry_digest_spec_sha256,
      46             :      &_gcry_digest_spec_sha224,
      47             : #endif
      48             : #if USE_SHA512
      49             :      &_gcry_digest_spec_sha512,
      50             :      &_gcry_digest_spec_sha384,
      51             : #endif
      52             : #if USE_SHA3
      53             :      &_gcry_digest_spec_sha3_224,
      54             :      &_gcry_digest_spec_sha3_256,
      55             :      &_gcry_digest_spec_sha3_384,
      56             :      &_gcry_digest_spec_sha3_512,
      57             :      &_gcry_digest_spec_shake128,
      58             :      &_gcry_digest_spec_shake256,
      59             : #endif
      60             : #if USE_GOST_R_3411_94
      61             :      &_gcry_digest_spec_gost3411_94,
      62             :      &_gcry_digest_spec_gost3411_cp,
      63             : #endif
      64             : #if USE_GOST_R_3411_12
      65             :      &_gcry_digest_spec_stribog_256,
      66             :      &_gcry_digest_spec_stribog_512,
      67             : #endif
      68             : #if USE_WHIRLPOOL
      69             :      &_gcry_digest_spec_whirlpool,
      70             : #endif
      71             : #if USE_RMD160
      72             :      &_gcry_digest_spec_rmd160,
      73             : #endif
      74             : #if USE_TIGER
      75             :      &_gcry_digest_spec_tiger,
      76             :      &_gcry_digest_spec_tiger1,
      77             :      &_gcry_digest_spec_tiger2,
      78             : #endif
      79             : #if USE_MD5
      80             :      &_gcry_digest_spec_md5,
      81             : #endif
      82             : #if USE_MD4
      83             :      &_gcry_digest_spec_md4,
      84             : #endif
      85             : #if USE_MD2
      86             :      &_gcry_digest_spec_md2,
      87             : #endif
      88             : #if USE_BLAKE2
      89             :      &_gcry_digest_spec_blake2b_512,
      90             :      &_gcry_digest_spec_blake2b_384,
      91             :      &_gcry_digest_spec_blake2b_256,
      92             :      &_gcry_digest_spec_blake2b_160,
      93             :      &_gcry_digest_spec_blake2s_256,
      94             :      &_gcry_digest_spec_blake2s_224,
      95             :      &_gcry_digest_spec_blake2s_160,
      96             :      &_gcry_digest_spec_blake2s_128,
      97             : #endif
      98             :      NULL
      99             :   };
     100             : 
     101             : 
     102             : typedef struct gcry_md_list
     103             : {
     104             :   gcry_md_spec_t *spec;
     105             :   struct gcry_md_list *next;
     106             :   size_t actual_struct_size;     /* Allocated size of this structure. */
     107             :   PROPERLY_ALIGNED_TYPE context;
     108             : } GcryDigestEntry;
     109             : 
     110             : /* This structure is put right after the gcry_md_hd_t buffer, so that
     111             :  * only one memory block is needed. */
     112             : struct gcry_md_context
     113             : {
     114             :   int  magic;
     115             :   size_t actual_handle_size;     /* Allocated size of this handle. */
     116             :   FILE  *debug;
     117             :   struct {
     118             :     unsigned int secure: 1;
     119             :     unsigned int finalized:1;
     120             :     unsigned int bugemu1:1;
     121             :     unsigned int hmac:1;
     122             :   } flags;
     123             :   GcryDigestEntry *list;
     124             : };
     125             : 
     126             : 
     127             : #define CTX_MAGIC_NORMAL 0x11071961
     128             : #define CTX_MAGIC_SECURE 0x16917011
     129             : 
     130             : static gcry_err_code_t md_enable (gcry_md_hd_t hd, int algo);
     131             : static void md_close (gcry_md_hd_t a);
     132             : static void md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen);
     133             : static byte *md_read( gcry_md_hd_t a, int algo );
     134             : static int md_get_algo( gcry_md_hd_t a );
     135             : static int md_digest_length( int algo );
     136             : static void md_start_debug ( gcry_md_hd_t a, const char *suffix );
     137             : static void md_stop_debug ( gcry_md_hd_t a );
     138             : 
     139             : 
     140             : 
     141             : static int
     142      144809 : map_algo (int algo)
     143             : {
     144      144809 :   return algo;
     145             : }
     146             : 
     147             : 
     148             : /* Return the spec structure for the hash algorithm ALGO.  For an
     149             :    unknown algorithm NULL is returned.  */
     150             : static gcry_md_spec_t *
     151      144809 : spec_from_algo (int algo)
     152             : {
     153             :   int idx;
     154             :   gcry_md_spec_t *spec;
     155             : 
     156      144809 :   algo = map_algo (algo);
     157             : 
     158     1486065 :   for (idx = 0; (spec = digest_list[idx]); idx++)
     159     1484595 :     if (algo == spec->algo)
     160      143339 :       return spec;
     161        1470 :   return NULL;
     162             : }
     163             : 
     164             : 
     165             : /* Lookup a hash's spec by its name.  */
     166             : static gcry_md_spec_t *
     167         127 : spec_from_name (const char *name)
     168             : {
     169             :   gcry_md_spec_t *spec;
     170             :   int idx;
     171             : 
     172        1797 :   for (idx=0; (spec = digest_list[idx]); idx++)
     173             :     {
     174        1773 :       if (!stricmp (name, spec->name))
     175         103 :         return spec;
     176             :     }
     177             : 
     178          24 :   return NULL;
     179             : }
     180             : 
     181             : 
     182             : /* Lookup a hash's spec by its OID.  */
     183             : static gcry_md_spec_t *
     184         175 : spec_from_oid (const char *oid)
     185             : {
     186             :   gcry_md_spec_t *spec;
     187             :   gcry_md_oid_spec_t *oid_specs;
     188             :   int idx, j;
     189             : 
     190        4510 :   for (idx=0; (spec = digest_list[idx]); idx++)
     191             :     {
     192        4383 :       oid_specs = spec->oids;
     193        4383 :       if (oid_specs)
     194             :         {
     195        9082 :           for (j = 0; oid_specs[j].oidstring; j++)
     196        5780 :             if (!stricmp (oid, oid_specs[j].oidstring))
     197          48 :               return spec;
     198             :         }
     199             :     }
     200             : 
     201         127 :   return NULL;
     202             : }
     203             : 
     204             : 
     205             : static gcry_md_spec_t *
     206         175 : search_oid (const char *oid, gcry_md_oid_spec_t *oid_spec)
     207             : {
     208             :   gcry_md_spec_t *spec;
     209             :   int i;
     210             : 
     211         175 :   if (!oid)
     212           0 :     return NULL;
     213             : 
     214         175 :   if (!strncmp (oid, "oid.", 4) || !strncmp (oid, "OID.", 4))
     215          48 :     oid += 4;
     216             : 
     217         175 :   spec = spec_from_oid (oid);
     218         175 :   if (spec && spec->oids)
     219             :     {
     220         192 :       for (i = 0; spec->oids[i].oidstring; i++)
     221         192 :         if (!stricmp (oid, spec->oids[i].oidstring))
     222             :           {
     223          48 :             if (oid_spec)
     224           0 :               *oid_spec = spec->oids[i];
     225          48 :             return spec;
     226             :           }
     227             :     }
     228             : 
     229         127 :   return NULL;
     230             : }
     231             : 
     232             : 
     233             : /****************
     234             :  * Map a string to the digest algo
     235             :  */
     236             : int
     237         175 : _gcry_md_map_name (const char *string)
     238             : {
     239             :   gcry_md_spec_t *spec;
     240             : 
     241         175 :   if (!string)
     242           0 :     return 0;
     243             : 
     244             :   /* If the string starts with a digit (optionally prefixed with
     245             :      either "OID." or "oid."), we first look into our table of ASN.1
     246             :      object identifiers to figure out the algorithm */
     247         175 :   spec = search_oid (string, NULL);
     248         175 :   if (spec)
     249          48 :     return spec->algo;
     250             : 
     251             :   /* Not found, search a matching digest name.  */
     252         127 :   spec = spec_from_name (string);
     253         127 :   if (spec)
     254         103 :     return spec->algo;
     255             : 
     256          24 :   return 0;
     257             : }
     258             : 
     259             : 
     260             : /****************
     261             :  * This function simply returns the name of the algorithm or some constant
     262             :  * string when there is no algo.  It will never return NULL.
     263             :  * Use  the macro gcry_md_test_algo() to check whether the algorithm
     264             :  * is valid.
     265             :  */
     266             : const char *
     267         126 : _gcry_md_algo_name (int algorithm)
     268             : {
     269             :   gcry_md_spec_t *spec;
     270             : 
     271         126 :   spec = spec_from_algo (algorithm);
     272         126 :   return spec ? spec->name : "?";
     273             : }
     274             : 
     275             : 
     276             : static gcry_err_code_t
     277        9500 : check_digest_algo (int algorithm)
     278             : {
     279             :   gcry_md_spec_t *spec;
     280             : 
     281        9500 :   spec = spec_from_algo (algorithm);
     282        9500 :   if (spec && !spec->flags.disabled)
     283        8030 :     return 0;
     284             : 
     285        1470 :   return GPG_ERR_DIGEST_ALGO;
     286             : 
     287             : }
     288             : 
     289             : 
     290             : /****************
     291             :  * Open a message digest handle for use with algorithm ALGO.
     292             :  * More algorithms may be added by md_enable(). The initial algorithm
     293             :  * may be 0.
     294             :  */
     295             : static gcry_err_code_t
     296       59232 : md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
     297             : {
     298       59232 :   gcry_err_code_t err = 0;
     299       59232 :   int secure = !!(flags & GCRY_MD_FLAG_SECURE);
     300       59232 :   int hmac =   !!(flags & GCRY_MD_FLAG_HMAC);
     301       59232 :   int bufsize = secure ? 512 : 1024;
     302             :   struct gcry_md_context *ctx;
     303             :   gcry_md_hd_t hd;
     304             :   size_t n;
     305             : 
     306             :   /* Allocate a memory area to hold the caller visible buffer with it's
     307             :    * control information and the data required by this module. Set the
     308             :    * context pointer at the beginning to this area.
     309             :    * We have to use this strange scheme because we want to hide the
     310             :    * internal data but have a variable sized buffer.
     311             :    *
     312             :    *    +---+------+---........------+-------------+
     313             :    *    !ctx! bctl !  buffer         ! private     !
     314             :    *    +---+------+---........------+-------------+
     315             :    *      !                           ^
     316             :    *      !---------------------------!
     317             :    *
     318             :    * We have to make sure that private is well aligned.
     319             :    */
     320       59232 :   n = sizeof (struct gcry_md_handle) + bufsize;
     321       59232 :   n = ((n + sizeof (PROPERLY_ALIGNED_TYPE) - 1)
     322             :        / sizeof (PROPERLY_ALIGNED_TYPE)) * sizeof (PROPERLY_ALIGNED_TYPE);
     323             : 
     324             :   /* Allocate and set the Context pointer to the private data */
     325       59232 :   if (secure)
     326          76 :     hd = xtrymalloc_secure (n + sizeof (struct gcry_md_context));
     327             :   else
     328       59156 :     hd = xtrymalloc (n + sizeof (struct gcry_md_context));
     329             : 
     330       59232 :   if (! hd)
     331           0 :     err = gpg_err_code_from_errno (errno);
     332             : 
     333       59232 :   if (! err)
     334             :     {
     335       59232 :       hd->ctx = ctx = (void *) ((char *) hd + n);
     336             :       /* Setup the globally visible data (bctl in the diagram).*/
     337       59232 :       hd->bufsize = n - sizeof (struct gcry_md_handle) + 1;
     338       59232 :       hd->bufpos = 0;
     339             : 
     340             :       /* Initialize the private data. */
     341       59232 :       memset (hd->ctx, 0, sizeof *hd->ctx);
     342       59232 :       ctx->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
     343       59232 :       ctx->actual_handle_size = n + sizeof (struct gcry_md_context);
     344       59232 :       ctx->flags.secure = secure;
     345       59232 :       ctx->flags.hmac = hmac;
     346       59232 :       ctx->flags.bugemu1 = !!(flags & GCRY_MD_FLAG_BUGEMU1);
     347             :     }
     348             : 
     349       59232 :   if (! err)
     350             :     {
     351             :       /* Hmmm, should we really do that? - yes [-wk] */
     352       59232 :       _gcry_fast_random_poll ();
     353             : 
     354       59232 :       if (algo)
     355             :         {
     356       59232 :           err = md_enable (hd, algo);
     357       59232 :           if (err)
     358           0 :             md_close (hd);
     359             :         }
     360             :     }
     361             : 
     362       59232 :   if (! err)
     363       59232 :     *h = hd;
     364             : 
     365       59232 :   return err;
     366             : }
     367             : 
     368             : /* Create a message digest object for algorithm ALGO.  FLAGS may be
     369             :    given as an bitwise OR of the gcry_md_flags values.  ALGO may be
     370             :    given as 0 if the algorithms to be used are later set using
     371             :    gcry_md_enable. H is guaranteed to be a valid handle or NULL on
     372             :    error.  */
     373             : gcry_err_code_t
     374       12459 : _gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
     375             : {
     376             :   gcry_err_code_t rc;
     377             :   gcry_md_hd_t hd;
     378             : 
     379       12459 :   if ((flags & ~(GCRY_MD_FLAG_SECURE
     380             :                  | GCRY_MD_FLAG_HMAC
     381             :                  | GCRY_MD_FLAG_BUGEMU1)))
     382           0 :     rc = GPG_ERR_INV_ARG;
     383             :   else
     384       12459 :     rc = md_open (&hd, algo, flags);
     385             : 
     386       12459 :   *h = rc? NULL : hd;
     387       12459 :   return rc;
     388             : }
     389             : 
     390             : 
     391             : 
     392             : static gcry_err_code_t
     393       59232 : md_enable (gcry_md_hd_t hd, int algorithm)
     394             : {
     395       59232 :   struct gcry_md_context *h = hd->ctx;
     396             :   gcry_md_spec_t *spec;
     397             :   GcryDigestEntry *entry;
     398       59232 :   gcry_err_code_t err = 0;
     399             : 
     400       59232 :   for (entry = h->list; entry; entry = entry->next)
     401           0 :     if (entry->spec->algo == algorithm)
     402           0 :       return 0; /* Already enabled */
     403             : 
     404       59232 :   spec = spec_from_algo (algorithm);
     405       59232 :   if (!spec)
     406             :     {
     407           0 :       log_debug ("md_enable: algorithm %d not available\n", algorithm);
     408           0 :       err = GPG_ERR_DIGEST_ALGO;
     409             :     }
     410             : 
     411             : 
     412       59232 :   if (!err && algorithm == GCRY_MD_MD5 && fips_mode ())
     413             :     {
     414           0 :       _gcry_inactivate_fips_mode ("MD5 used");
     415           0 :       if (_gcry_enforced_fips_mode () )
     416             :         {
     417             :           /* We should never get to here because we do not register
     418             :              MD5 in enforced fips mode. But better throw an error.  */
     419           0 :           err = GPG_ERR_DIGEST_ALGO;
     420             :         }
     421             :     }
     422             : 
     423       59232 :   if (!err && h->flags.hmac && spec->read == NULL)
     424             :     {
     425             :       /* Expandable output function cannot act as part of HMAC. */
     426           0 :       err = GPG_ERR_DIGEST_ALGO;
     427             :     }
     428             : 
     429       59232 :   if (!err)
     430             :     {
     431       59232 :       size_t size = (sizeof (*entry)
     432       59232 :                      + spec->contextsize * (h->flags.hmac? 3 : 1)
     433             :                      - sizeof (entry->context));
     434             : 
     435             :       /* And allocate a new list entry. */
     436       59232 :       if (h->flags.secure)
     437          76 :         entry = xtrymalloc_secure (size);
     438             :       else
     439       59156 :         entry = xtrymalloc (size);
     440             : 
     441       59232 :       if (! entry)
     442           0 :         err = gpg_err_code_from_errno (errno);
     443             :       else
     444             :         {
     445       59232 :           entry->spec = spec;
     446       59232 :           entry->next = h->list;
     447       59232 :           entry->actual_struct_size = size;
     448       59232 :           h->list = entry;
     449             : 
     450             :           /* And init this instance. */
     451      118464 :           entry->spec->init (&entry->context.c,
     452       59232 :                              h->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0);
     453             :         }
     454             :     }
     455             : 
     456       59232 :   return err;
     457             : }
     458             : 
     459             : 
     460             : gcry_err_code_t
     461           0 : _gcry_md_enable (gcry_md_hd_t hd, int algorithm)
     462             : {
     463           0 :   return md_enable (hd, algorithm);
     464             : }
     465             : 
     466             : 
     467             : static gcry_err_code_t
     468        3496 : md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
     469             : {
     470        3496 :   gcry_err_code_t err = 0;
     471        3496 :   struct gcry_md_context *a = ahd->ctx;
     472             :   struct gcry_md_context *b;
     473             :   GcryDigestEntry *ar, *br;
     474             :   gcry_md_hd_t bhd;
     475             :   size_t n;
     476             : 
     477        3496 :   if (ahd->bufpos)
     478           0 :     md_write (ahd, NULL, 0);
     479             : 
     480        3496 :   n = (char *) ahd->ctx - (char *) ahd;
     481        3496 :   if (a->flags.secure)
     482           0 :     bhd = xtrymalloc_secure (n + sizeof (struct gcry_md_context));
     483             :   else
     484        3496 :     bhd = xtrymalloc (n + sizeof (struct gcry_md_context));
     485             : 
     486        3496 :   if (!bhd)
     487             :     {
     488           0 :       err = gpg_err_code_from_syserror ();
     489           0 :       goto leave;
     490             :     }
     491             : 
     492        3496 :   bhd->ctx = b = (void *) ((char *) bhd + n);
     493             :   /* No need to copy the buffer due to the write above. */
     494        3496 :   gcry_assert (ahd->bufsize == (n - sizeof (struct gcry_md_handle) + 1));
     495        3496 :   bhd->bufsize = ahd->bufsize;
     496        3496 :   bhd->bufpos = 0;
     497        3496 :   gcry_assert (! ahd->bufpos);
     498        3496 :   memcpy (b, a, sizeof *a);
     499        3496 :   b->list = NULL;
     500        3496 :   b->debug = NULL;
     501             : 
     502             :   /* Copy the complete list of algorithms.  The copied list is
     503             :      reversed, but that doesn't matter. */
     504        6992 :   for (ar = a->list; ar; ar = ar->next)
     505             :     {
     506        3496 :       if (a->flags.secure)
     507           0 :         br = xtrymalloc_secure (ar->actual_struct_size);
     508             :       else
     509        3496 :         br = xtrymalloc (ar->actual_struct_size);
     510        3496 :       if (!br)
     511             :         {
     512           0 :           err = gpg_err_code_from_syserror ();
     513           0 :           md_close (bhd);
     514           0 :           goto leave;
     515             :         }
     516             : 
     517        3496 :       memcpy (br, ar, ar->actual_struct_size);
     518        3496 :       br->next = b->list;
     519        3496 :       b->list = br;
     520             :     }
     521             : 
     522        3496 :   if (a->debug)
     523           0 :     md_start_debug (bhd, "unknown");
     524             : 
     525        3496 :   *b_hd = bhd;
     526             : 
     527             :  leave:
     528        3496 :   return err;
     529             : }
     530             : 
     531             : 
     532             : gcry_err_code_t
     533        3496 : _gcry_md_copy (gcry_md_hd_t *handle, gcry_md_hd_t hd)
     534             : {
     535             :   gcry_err_code_t rc;
     536             : 
     537        3496 :   rc = md_copy (hd, handle);
     538        3496 :   if (rc)
     539           0 :     *handle = NULL;
     540        3496 :   return rc;
     541             : }
     542             : 
     543             : 
     544             : /*
     545             :  * Reset all contexts and discard any buffered stuff.  This may be used
     546             :  * instead of a md_close(); md_open().
     547             :  */
     548             : void
     549      331816 : _gcry_md_reset (gcry_md_hd_t a)
     550             : {
     551             :   GcryDigestEntry *r;
     552             : 
     553             :   /* Note: We allow this even in fips non operational mode.  */
     554             : 
     555      331816 :   a->bufpos = a->ctx->flags.finalized = 0;
     556             : 
     557      331816 :   if (a->ctx->flags.hmac)
     558      590930 :     for (r = a->ctx->list; r; r = r->next)
     559             :       {
     560      295465 :         memcpy (r->context.c, r->context.c + r->spec->contextsize,
     561      295465 :                 r->spec->contextsize);
     562             :       }
     563             :   else
     564       72702 :     for (r = a->ctx->list; r; r = r->next)
     565             :       {
     566       36351 :         memset (r->context.c, 0, r->spec->contextsize);
     567       72702 :         (*r->spec->init) (&r->context.c,
     568       36351 :                           a->ctx->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0);
     569             :       }
     570      331816 : }
     571             : 
     572             : 
     573             : static void
     574       62726 : md_close (gcry_md_hd_t a)
     575             : {
     576             :   GcryDigestEntry *r, *r2;
     577             : 
     578       62726 :   if (! a)
     579           0 :     return;
     580       62726 :   if (a->ctx->debug)
     581           0 :     md_stop_debug (a);
     582      125452 :   for (r = a->ctx->list; r; r = r2)
     583             :     {
     584       62726 :       r2 = r->next;
     585       62726 :       wipememory (r, r->actual_struct_size);
     586       62726 :       xfree (r);
     587             :     }
     588             : 
     589       62726 :   wipememory (a, a->ctx->actual_handle_size);
     590       62726 :   xfree(a);
     591             : }
     592             : 
     593             : 
     594             : void
     595       15953 : _gcry_md_close (gcry_md_hd_t hd)
     596             : {
     597             :   /* Note: We allow this even in fips non operational mode.  */
     598       15953 :   md_close (hd);
     599       15953 : }
     600             : 
     601             : 
     602             : static void
     603    35961922 : md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen)
     604             : {
     605             :   GcryDigestEntry *r;
     606             : 
     607    35961922 :   if (a->ctx->debug)
     608             :     {
     609           0 :       if (a->bufpos && fwrite (a->buf, a->bufpos, 1, a->ctx->debug) != 1)
     610           0 :         BUG();
     611           0 :       if (inlen && fwrite (inbuf, inlen, 1, a->ctx->debug) != 1)
     612           0 :         BUG();
     613             :     }
     614             : 
     615    71923844 :   for (r = a->ctx->list; r; r = r->next)
     616             :     {
     617    35961922 :       if (a->bufpos)
     618       32186 :         (*r->spec->write) (&r->context.c, a->buf, a->bufpos);
     619    35961922 :       (*r->spec->write) (&r->context.c, inbuf, inlen);
     620             :     }
     621    35961922 :   a->bufpos = 0;
     622    35961922 : }
     623             : 
     624             : 
     625             : /* Note that this function may be used after finalize and read to keep
     626             :    on writing to the transform function so to mitigate timing
     627             :    attacks.  */
     628             : void
     629    35902546 : _gcry_md_write (gcry_md_hd_t hd, const void *inbuf, size_t inlen)
     630             : {
     631    35902546 :   md_write (hd, inbuf, inlen);
     632    35902546 : }
     633             : 
     634             : 
     635             : static void
     636      393902 : md_final (gcry_md_hd_t a)
     637             : {
     638             :   GcryDigestEntry *r;
     639             : 
     640      393902 :   if (a->ctx->flags.finalized)
     641       18199 :     return;
     642             : 
     643      375703 :   if (a->bufpos)
     644           0 :     md_write (a, NULL, 0);
     645             : 
     646      751406 :   for (r = a->ctx->list; r; r = r->next)
     647      375703 :     (*r->spec->final) (&r->context.c);
     648             : 
     649      375703 :   a->ctx->flags.finalized = 1;
     650             : 
     651      375703 :   if (!a->ctx->flags.hmac)
     652       87692 :     return;
     653             : 
     654      576022 :   for (r = a->ctx->list; r; r = r->next)
     655             :     {
     656             :       byte *p;
     657      288011 :       size_t dlen = r->spec->mdlen;
     658             :       byte *hash;
     659             :       gcry_err_code_t err;
     660             : 
     661      288011 :       if (r->spec->read == NULL)
     662           0 :         continue;
     663             : 
     664      288011 :       p = r->spec->read (&r->context.c);
     665             : 
     666      288011 :       if (a->ctx->flags.secure)
     667         478 :         hash = xtrymalloc_secure (dlen);
     668             :       else
     669      287533 :         hash = xtrymalloc (dlen);
     670      288011 :       if (!hash)
     671             :         {
     672           0 :           err = gpg_err_code_from_errno (errno);
     673           0 :           _gcry_fatal_error (err, NULL);
     674             :         }
     675             : 
     676      288011 :       memcpy (hash, p, dlen);
     677      288011 :       memcpy (r->context.c, r->context.c + r->spec->contextsize * 2,
     678      288011 :               r->spec->contextsize);
     679      288011 :       (*r->spec->write) (&r->context.c, hash, dlen);
     680      288011 :       (*r->spec->final) (&r->context.c);
     681      288011 :       xfree (hash);
     682             :     }
     683             : }
     684             : 
     685             : 
     686             : static gcry_err_code_t
     687          50 : md_setkey (gcry_md_hd_t h, const unsigned char *key, size_t keylen)
     688             : {
     689          50 :   gcry_err_code_t rc = 0;
     690             :   GcryDigestEntry *r;
     691          50 :   int algo_had_setkey = 0;
     692             : 
     693          50 :   if (!h->ctx->list)
     694           0 :     return GPG_ERR_DIGEST_ALGO; /* Might happen if no algo is enabled.  */
     695             : 
     696          50 :   if (h->ctx->flags.hmac)
     697           0 :     return GPG_ERR_DIGEST_ALGO; /* Tried md_setkey for HMAC md. */
     698             : 
     699         100 :   for (r = h->ctx->list; r; r = r->next)
     700             :     {
     701          50 :       switch (r->spec->algo)
     702             :         {
     703             :         /* TODO? add spec->init_with_key? */
     704             :         case GCRY_MD_BLAKE2B_512:
     705             :         case GCRY_MD_BLAKE2B_384:
     706             :         case GCRY_MD_BLAKE2B_256:
     707             :         case GCRY_MD_BLAKE2B_160:
     708             :         case GCRY_MD_BLAKE2S_256:
     709             :         case GCRY_MD_BLAKE2S_224:
     710             :         case GCRY_MD_BLAKE2S_160:
     711             :         case GCRY_MD_BLAKE2S_128:
     712          50 :           algo_had_setkey = 1;
     713          50 :           memset (r->context.c, 0, r->spec->contextsize);
     714         100 :           rc = _gcry_blake2_init_with_key (r->context.c,
     715          50 :                                            h->ctx->flags.bugemu1
     716          50 :                                              ? GCRY_MD_FLAG_BUGEMU1:0,
     717          50 :                                            key, keylen, r->spec->algo);
     718          50 :           break;
     719             :         default:
     720           0 :           rc = GPG_ERR_DIGEST_ALGO;
     721           0 :           break;
     722             :         }
     723             : 
     724          50 :       if (rc)
     725           0 :         break;
     726             :     }
     727             : 
     728          50 :   if (rc && !algo_had_setkey)
     729             :     {
     730             :       /* None of algorithms had setkey implementation, so contexts were not
     731             :        * modified. Just return error. */
     732           0 :       return rc;
     733             :     }
     734          50 :   else if (rc && algo_had_setkey)
     735             :     {
     736             :       /* Some of the contexts have been modified, but got error. Reset
     737             :        * all contexts. */
     738           0 :       _gcry_md_reset (h);
     739           0 :       return rc;
     740             :     }
     741             : 
     742             :   /* Successful md_setkey implies reset. */
     743          50 :   h->bufpos = h->ctx->flags.finalized = 0;
     744             : 
     745          50 :   return 0;
     746             : }
     747             : 
     748             : 
     749             : static gcry_err_code_t
     750        8282 : prepare_macpads (gcry_md_hd_t a, const unsigned char *key, size_t keylen)
     751             : {
     752             :   GcryDigestEntry *r;
     753             : 
     754        8282 :   if (!a->ctx->list)
     755           0 :     return GPG_ERR_DIGEST_ALGO; /* Might happen if no algo is enabled.  */
     756             : 
     757        8282 :   if (!a->ctx->flags.hmac)
     758           0 :     return GPG_ERR_DIGEST_ALGO; /* Tried prepare_macpads for non-HMAC md. */
     759             : 
     760       16564 :   for (r = a->ctx->list; r; r = r->next)
     761             :     {
     762             :       const unsigned char *k;
     763             :       size_t k_len;
     764        8282 :       unsigned char *key_allocated = NULL;
     765             :       int macpad_Bsize;
     766             :       int i;
     767             : 
     768        8282 :       switch (r->spec->algo)
     769             :         {
     770             :         /* TODO: add spec->blocksize */
     771             :         case GCRY_MD_SHA3_224:
     772         296 :           macpad_Bsize = 1152 / 8;
     773         296 :           break;
     774             :         case GCRY_MD_SHA3_256:
     775         296 :           macpad_Bsize = 1088 / 8;
     776         296 :           break;
     777             :         case GCRY_MD_SHA3_384:
     778         292 :           macpad_Bsize = 832 / 8;
     779         292 :           break;
     780             :         case GCRY_MD_SHA3_512:
     781         296 :           macpad_Bsize = 576 / 8;
     782         296 :           break;
     783             :         case GCRY_MD_SHA384:
     784             :         case GCRY_MD_SHA512:
     785             :         case GCRY_MD_BLAKE2B_512:
     786             :         case GCRY_MD_BLAKE2B_384:
     787             :         case GCRY_MD_BLAKE2B_256:
     788             :         case GCRY_MD_BLAKE2B_160:
     789        1694 :           macpad_Bsize = 128;
     790        1694 :           break;
     791             :         case GCRY_MD_GOSTR3411_94:
     792             :         case GCRY_MD_GOSTR3411_CP:
     793         559 :           macpad_Bsize = 32;
     794         559 :           break;
     795             :         default:
     796        4849 :           macpad_Bsize = 64;
     797        4849 :           break;
     798             :         }
     799             : 
     800        8282 :       if ( keylen > macpad_Bsize )
     801             :         {
     802         111 :           k = key_allocated = xtrymalloc_secure (r->spec->mdlen);
     803         111 :           if (!k)
     804           0 :             return gpg_err_code_from_errno (errno);
     805         111 :           _gcry_md_hash_buffer (r->spec->algo, key_allocated, key, keylen);
     806         111 :           k_len = r->spec->mdlen;
     807         111 :           gcry_assert ( k_len <= macpad_Bsize );
     808             :         }
     809             :       else
     810             :         {
     811        8171 :           k = key;
     812        8171 :           k_len = keylen;
     813             :         }
     814             : 
     815       16564 :       (*r->spec->init) (&r->context.c,
     816        8282 :                         a->ctx->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0);
     817        8282 :       a->bufpos = 0;
     818       81588 :       for (i=0; i < k_len; i++ )
     819       73306 :         _gcry_md_putc (a, k[i] ^ 0x36);
     820      614592 :       for (; i < macpad_Bsize; i++ )
     821      606310 :         _gcry_md_putc (a, 0x36);
     822        8282 :       (*r->spec->write) (&r->context.c, a->buf, a->bufpos);
     823        8282 :       memcpy (r->context.c + r->spec->contextsize, r->context.c,
     824        8282 :               r->spec->contextsize);
     825             : 
     826       16564 :       (*r->spec->init) (&r->context.c,
     827        8282 :                         a->ctx->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0);
     828        8282 :       a->bufpos = 0;
     829       81588 :       for (i=0; i < k_len; i++ )
     830       73306 :         _gcry_md_putc (a, k[i] ^ 0x5c);
     831      614592 :       for (; i < macpad_Bsize; i++ )
     832      606310 :         _gcry_md_putc (a, 0x5c);
     833        8282 :       (*r->spec->write) (&r->context.c, a->buf, a->bufpos);
     834        8282 :       memcpy (r->context.c + r->spec->contextsize*2, r->context.c,
     835        8282 :               r->spec->contextsize);
     836             : 
     837        8282 :       xfree (key_allocated);
     838             :     }
     839             : 
     840        8282 :   a->bufpos = 0;
     841        8282 :   return 0;
     842             : }
     843             : 
     844             : 
     845             : gcry_err_code_t
     846      347129 : _gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
     847             : {
     848      347129 :   gcry_err_code_t rc = 0;
     849             : 
     850             :   (void)buflen; /* Currently not used.  */
     851             : 
     852      347129 :   switch (cmd)
     853             :     {
     854             :     case GCRYCTL_FINALIZE:
     855      347129 :       md_final (hd);
     856      347129 :       break;
     857             :     case GCRYCTL_START_DUMP:
     858           0 :       md_start_debug (hd, buffer);
     859           0 :       break;
     860             :     case GCRYCTL_STOP_DUMP:
     861           0 :       md_stop_debug ( hd );
     862           0 :       break;
     863             :     default:
     864           0 :       rc = GPG_ERR_INV_OP;
     865             :     }
     866      347129 :   return rc;
     867             : }
     868             : 
     869             : 
     870             : gcry_err_code_t
     871        8332 : _gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen)
     872             : {
     873             :   gcry_err_code_t rc;
     874             : 
     875        8332 :   if (hd->ctx->flags.hmac)
     876             :     {
     877        8282 :       rc = prepare_macpads (hd, key, keylen);
     878        8282 :       if (!rc)
     879        8282 :         _gcry_md_reset (hd);
     880             :     }
     881             :   else
     882             :     {
     883          50 :       rc = md_setkey (hd, key, keylen);
     884             :     }
     885             : 
     886        8332 :   return rc;
     887             : }
     888             : 
     889             : 
     890             : /* The new debug interface.  If SUFFIX is a string it creates an debug
     891             :    file for the context HD.  IF suffix is NULL, the file is closed and
     892             :    debugging is stopped.  */
     893             : void
     894           0 : _gcry_md_debug (gcry_md_hd_t hd, const char *suffix)
     895             : {
     896           0 :   if (suffix)
     897           0 :     md_start_debug (hd, suffix);
     898             :   else
     899           0 :     md_stop_debug (hd);
     900           0 : }
     901             : 
     902             : 
     903             : /****************
     904             :  * If ALGO is null get the digest for the used algo (which should be
     905             :  * only one)
     906             :  */
     907             : static byte *
     908      342616 : md_read( gcry_md_hd_t a, int algo )
     909             : {
     910      342616 :   GcryDigestEntry *r = a->ctx->list;
     911             : 
     912      342616 :   if (! algo)
     913             :     {
     914             :       /* Return the first algorithm */
     915      281339 :       if (r)
     916             :         {
     917      281339 :           if (r->next)
     918           0 :             log_debug ("more than one algorithm in md_read(0)\n");
     919      281339 :           if (r->spec->read)
     920      281339 :             return r->spec->read (&r->context.c);
     921             :         }
     922             :     }
     923             :   else
     924             :     {
     925       61277 :       for (r = a->ctx->list; r; r = r->next)
     926       61277 :         if (r->spec->algo == algo)
     927             :           {
     928       61277 :             if (r->spec->read)
     929       61277 :               return r->spec->read (&r->context.c);
     930           0 :             break;
     931             :           }
     932             :     }
     933             : 
     934           0 :   if (r && !r->spec->read)
     935           0 :     _gcry_fatal_error (GPG_ERR_DIGEST_ALGO,
     936             :                        "requested algo has no fixed digest length");
     937             :   else
     938           0 :     _gcry_fatal_error (GPG_ERR_DIGEST_ALGO, "requested algo not in md context");
     939             :   return NULL;
     940             : }
     941             : 
     942             : 
     943             : /*
     944             :  * Read out the complete digest, this function implictly finalizes
     945             :  * the hash.
     946             :  */
     947             : byte *
     948      295843 : _gcry_md_read (gcry_md_hd_t hd, int algo)
     949             : {
     950             :   /* This function is expected to always return a digest, thus we
     951             :      can't return an error which we actually should do in
     952             :      non-operational state.  */
     953      295843 :   _gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
     954      295843 :   return md_read (hd, algo);
     955             : }
     956             : 
     957             : 
     958             : /****************
     959             :  * If ALGO is null get the digest for the used algo (which should be
     960             :  * only one)
     961             :  */
     962             : static gcry_err_code_t
     963       17878 : md_extract(gcry_md_hd_t a, int algo, void *out, size_t outlen)
     964             : {
     965       17878 :   GcryDigestEntry *r = a->ctx->list;
     966             : 
     967       17878 :   if (!algo)
     968             :     {
     969             :       /* Return the first algorithm */
     970           0 :       if (r && r->spec->extract)
     971             :         {
     972           0 :           if (r->next)
     973           0 :             log_debug ("more than one algorithm in md_extract(0)\n");
     974           0 :           r->spec->extract (&r->context.c, out, outlen);
     975           0 :           return 0;
     976             :         }
     977             :     }
     978             :   else
     979             :     {
     980       17878 :       for (r = a->ctx->list; r; r = r->next)
     981       17878 :         if (r->spec->algo == algo && r->spec->extract)
     982             :           {
     983       17878 :             r->spec->extract (&r->context.c, out, outlen);
     984       17878 :             return 0;
     985             :           }
     986             :     }
     987             : 
     988           0 :   return GPG_ERR_DIGEST_ALGO;
     989             : }
     990             : 
     991             : 
     992             : /*
     993             :  * Expand the output from XOF class digest, this function implictly finalizes
     994             :  * the hash.
     995             :  */
     996             : gcry_err_code_t
     997       17878 : _gcry_md_extract (gcry_md_hd_t hd, int algo, void *out, size_t outlen)
     998             : {
     999       17878 :   _gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
    1000       17878 :   return md_extract (hd, algo, out, outlen);
    1001             : }
    1002             : 
    1003             : 
    1004             : /*
    1005             :  * Read out an intermediate digest.  Not yet functional.
    1006             :  */
    1007             : gcry_err_code_t
    1008           0 : _gcry_md_get (gcry_md_hd_t hd, int algo, byte *buffer, int buflen)
    1009             : {
    1010             :   (void)hd;
    1011             :   (void)algo;
    1012             :   (void)buffer;
    1013             :   (void)buflen;
    1014             : 
    1015             :   /*md_digest ... */
    1016           0 :   fips_signal_error ("unimplemented function called");
    1017           0 :   return GPG_ERR_INTERNAL;
    1018             : }
    1019             : 
    1020             : 
    1021             : /*
    1022             :  * Shortcut function to hash a buffer with a given algo. The only
    1023             :  * guaranteed supported algorithms are RIPE-MD160 and SHA-1. The
    1024             :  * supplied digest buffer must be large enough to store the resulting
    1025             :  * hash.  No error is returned, the function will abort on an invalid
    1026             :  * algo.  DISABLED_ALGOS are ignored here.  */
    1027             : void
    1028       63589 : _gcry_md_hash_buffer (int algo, void *digest,
    1029             :                       const void *buffer, size_t length)
    1030             : {
    1031       63589 :   if (algo == GCRY_MD_SHA1)
    1032       24132 :     _gcry_sha1_hash_buffer (digest, buffer, length);
    1033       39457 :   else if (algo == GCRY_MD_RMD160 && !fips_mode () )
    1034         100 :     _gcry_rmd160_hash_buffer (digest, buffer, length);
    1035             :   else
    1036             :     {
    1037             :       /* For the others we do not have a fast function, so we use the
    1038             :          normal functions. */
    1039             :       gcry_md_hd_t h;
    1040             :       gpg_err_code_t err;
    1041             : 
    1042       39357 :       if (algo == GCRY_MD_MD5 && fips_mode ())
    1043             :         {
    1044           0 :           _gcry_inactivate_fips_mode ("MD5 used");
    1045           0 :           if (_gcry_enforced_fips_mode () )
    1046             :             {
    1047             :               /* We should never get to here because we do not register
    1048             :                  MD5 in enforced fips mode.  */
    1049           0 :               _gcry_fips_noreturn ();
    1050             :             }
    1051             :         }
    1052             : 
    1053       39357 :       err = md_open (&h, algo, 0);
    1054       39357 :       if (err)
    1055           0 :         log_bug ("gcry_md_open failed for algo %d: %s",
    1056             :                  algo, gpg_strerror (gcry_error(err)));
    1057       39357 :       md_write (h, (byte *) buffer, length);
    1058       39357 :       md_final (h);
    1059       39357 :       memcpy (digest, md_read (h, algo), md_digest_length (algo));
    1060       39357 :       md_close (h);
    1061             :     }
    1062       63589 : }
    1063             : 
    1064             : 
    1065             : /* Shortcut function to hash multiple buffers with a given algo.  In
    1066             :    contrast to gcry_md_hash_buffer, this function returns an error on
    1067             :    invalid arguments or on other problems; disabled algorithms are
    1068             :    _not_ ignored but flagged as an error.
    1069             : 
    1070             :    The data to sign is taken from the array IOV which has IOVCNT items.
    1071             : 
    1072             :    The only supported flag in FLAGS is GCRY_MD_FLAG_HMAC which turns
    1073             :    this function into a HMAC function; the first item in IOV is then
    1074             :    used as the key.
    1075             : 
    1076             :    On success 0 is returned and resulting hash or HMAC is stored at
    1077             :    DIGEST which must have been provided by the caller with an
    1078             :    appropriate length.  */
    1079             : gpg_err_code_t
    1080        7422 : _gcry_md_hash_buffers (int algo, unsigned int flags, void *digest,
    1081             :                        const gcry_buffer_t *iov, int iovcnt)
    1082             : {
    1083             :   int hmac;
    1084             : 
    1085        7422 :   if (!iov || iovcnt < 0)
    1086           0 :     return GPG_ERR_INV_ARG;
    1087        7422 :   if (flags & ~(GCRY_MD_FLAG_HMAC))
    1088           0 :     return GPG_ERR_INV_ARG;
    1089             : 
    1090        7422 :   hmac = !!(flags & GCRY_MD_FLAG_HMAC);
    1091        7422 :   if (hmac && iovcnt < 1)
    1092           0 :     return GPG_ERR_INV_ARG;
    1093             : 
    1094        7422 :   if (algo == GCRY_MD_SHA1 && !hmac)
    1095           6 :     _gcry_sha1_hash_buffers (digest, iov, iovcnt);
    1096             :   else
    1097             :     {
    1098             :       /* For the others we do not have a fast function, so we use the
    1099             :          normal functions. */
    1100             :       gcry_md_hd_t h;
    1101             :       gpg_err_code_t rc;
    1102             :       int dlen;
    1103             : 
    1104        7416 :       if (algo == GCRY_MD_MD5 && fips_mode ())
    1105             :         {
    1106           0 :           _gcry_inactivate_fips_mode ("MD5 used");
    1107           0 :           if (_gcry_enforced_fips_mode () )
    1108             :             {
    1109             :               /* We should never get to here because we do not register
    1110             :                  MD5 in enforced fips mode.  */
    1111           0 :               _gcry_fips_noreturn ();
    1112             :             }
    1113             :         }
    1114             : 
    1115             :       /* Detect SHAKE128 like algorithms which we can't use because
    1116             :        * our API does not allow for a variable length digest.  */
    1117        7416 :       dlen = md_digest_length (algo);
    1118        7416 :       if (!dlen)
    1119           0 :         return GPG_ERR_DIGEST_ALGO;
    1120             : 
    1121        7416 :       rc = md_open (&h, algo, (hmac? GCRY_MD_FLAG_HMAC:0));
    1122        7416 :       if (rc)
    1123           0 :         return rc;
    1124             : 
    1125        7416 :       if (hmac)
    1126             :         {
    1127           2 :           rc = _gcry_md_setkey (h,
    1128           1 :                                 (const char*)iov[0].data + iov[0].off,
    1129             :                                 iov[0].len);
    1130           1 :           if (rc)
    1131             :             {
    1132           0 :               md_close (h);
    1133           0 :               return rc;
    1134             :             }
    1135           1 :           iov++; iovcnt--;
    1136             :         }
    1137       27435 :       for (;iovcnt; iov++, iovcnt--)
    1138       20019 :         md_write (h, (const char*)iov[0].data + iov[0].off, iov[0].len);
    1139        7416 :       md_final (h);
    1140        7416 :       memcpy (digest, md_read (h, algo), dlen);
    1141        7416 :       md_close (h);
    1142             :     }
    1143             : 
    1144        7422 :   return 0;
    1145             : }
    1146             : 
    1147             : 
    1148             : static int
    1149           0 : md_get_algo (gcry_md_hd_t a)
    1150             : {
    1151           0 :   GcryDigestEntry *r = a->ctx->list;
    1152             : 
    1153           0 :   if (r && r->next)
    1154             :     {
    1155           0 :       fips_signal_error ("possible usage error");
    1156           0 :       log_error ("WARNING: more than one algorithm in md_get_algo()\n");
    1157             :     }
    1158           0 :   return r ? r->spec->algo : 0;
    1159             : }
    1160             : 
    1161             : 
    1162             : int
    1163           0 : _gcry_md_get_algo (gcry_md_hd_t hd)
    1164             : {
    1165           0 :   return md_get_algo (hd);
    1166             : }
    1167             : 
    1168             : 
    1169             : /****************
    1170             :  * Return the length of the digest
    1171             :  */
    1172             : static int
    1173       75002 : md_digest_length (int algorithm)
    1174             : {
    1175             :   gcry_md_spec_t *spec;
    1176             : 
    1177       75002 :   spec = spec_from_algo (algorithm);
    1178       75002 :   return spec? spec->mdlen : 0;
    1179             : }
    1180             : 
    1181             : 
    1182             : /****************
    1183             :  * Return the length of the digest in bytes.
    1184             :  * This function will return 0 in case of errors.
    1185             :  */
    1186             : unsigned int
    1187       28229 : _gcry_md_get_algo_dlen (int algorithm)
    1188             : {
    1189       28229 :   return md_digest_length (algorithm);
    1190             : }
    1191             : 
    1192             : 
    1193             : /* Hmmm: add a mode to enumerate the OIDs
    1194             :  *      to make g10/sig-check.c more portable */
    1195             : static const byte *
    1196         906 : md_asn_oid (int algorithm, size_t *asnlen, size_t *mdlen)
    1197             : {
    1198             :   gcry_md_spec_t *spec;
    1199         906 :   const byte *asnoid = NULL;
    1200             : 
    1201         906 :   spec = spec_from_algo (algorithm);
    1202         906 :   if (spec)
    1203             :     {
    1204         906 :       if (asnlen)
    1205         906 :         *asnlen = spec->asnlen;
    1206         906 :       if (mdlen)
    1207           0 :         *mdlen = spec->mdlen;
    1208         906 :       asnoid = spec->asnoid;
    1209             :     }
    1210             :   else
    1211           0 :     log_bug ("no ASN.1 OID for md algo %d\n", algorithm);
    1212             : 
    1213         906 :   return asnoid;
    1214             : }
    1215             : 
    1216             : 
    1217             : /****************
    1218             :  * Return information about the given cipher algorithm
    1219             :  * WHAT select the kind of information returned:
    1220             :  *  GCRYCTL_TEST_ALGO:
    1221             :  *      Returns 0 when the specified algorithm is available for use.
    1222             :  *      buffer and nbytes must be zero.
    1223             :  *  GCRYCTL_GET_ASNOID:
    1224             :  *      Return the ASNOID of the algorithm in buffer. if buffer is NULL, only
    1225             :  *      the required length is returned.
    1226             :  *  GCRYCTL_SELFTEST
    1227             :  *      Helper for the regression tests - shall not be used by applications.
    1228             :  *
    1229             :  * Note:  Because this function is in most cases used to return an
    1230             :  * integer value, we can make it easier for the caller to just look at
    1231             :  * the return value.  The caller will in all cases consult the value
    1232             :  * and thereby detecting whether a error occurred or not (i.e. while checking
    1233             :  * the block size)
    1234             :  */
    1235             : gcry_err_code_t
    1236        9533 : _gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes)
    1237             : {
    1238             :   gcry_err_code_t rc;
    1239             : 
    1240        9533 :   switch (what)
    1241             :     {
    1242             :     case GCRYCTL_TEST_ALGO:
    1243        8594 :       if (buffer || nbytes)
    1244           0 :         rc = GPG_ERR_INV_ARG;
    1245             :       else
    1246        8594 :         rc = check_digest_algo (algo);
    1247        8594 :       break;
    1248             : 
    1249             :     case GCRYCTL_GET_ASNOID:
    1250             :       /* We need to check that the algo is available because
    1251             :          md_asn_oid would otherwise raise an assertion. */
    1252         906 :       rc = check_digest_algo (algo);
    1253         906 :       if (!rc)
    1254             :         {
    1255             :           const char unsigned *asn;
    1256             :           size_t asnlen;
    1257             : 
    1258         906 :           asn = md_asn_oid (algo, &asnlen, NULL);
    1259         906 :           if (buffer && (*nbytes >= asnlen))
    1260             :             {
    1261         906 :               memcpy (buffer, asn, asnlen);
    1262         906 :               *nbytes = asnlen;
    1263             :             }
    1264           0 :           else if (!buffer && nbytes)
    1265           0 :             *nbytes = asnlen;
    1266             :           else
    1267             :             {
    1268           0 :               if (buffer)
    1269           0 :                 rc = GPG_ERR_TOO_SHORT;
    1270             :               else
    1271           0 :                 rc = GPG_ERR_INV_ARG;
    1272             :             }
    1273             :         }
    1274         906 :       break;
    1275             : 
    1276             :     case GCRYCTL_SELFTEST:
    1277             :       /* Helper function for the regression tests.  */
    1278          33 :       rc = gpg_err_code (_gcry_md_selftest (algo, nbytes? (int)*nbytes : 0,
    1279             :                                              NULL));
    1280          33 :       break;
    1281             : 
    1282             :     default:
    1283           0 :       rc = GPG_ERR_INV_OP;
    1284           0 :       break;
    1285             :   }
    1286             : 
    1287        9533 :   return rc;
    1288             : }
    1289             : 
    1290             : 
    1291             : static void
    1292           0 : md_start_debug ( gcry_md_hd_t md, const char *suffix )
    1293             : {
    1294             :   static int idx=0;
    1295             :   char buf[50];
    1296             : 
    1297           0 :   if (fips_mode ())
    1298           0 :     return;
    1299             : 
    1300           0 :   if ( md->ctx->debug )
    1301             :     {
    1302           0 :       log_debug("Oops: md debug already started\n");
    1303           0 :       return;
    1304             :     }
    1305           0 :   idx++;
    1306           0 :   snprintf (buf, DIM(buf)-1, "dbgmd-%05d.%.10s", idx, suffix );
    1307           0 :   md->ctx->debug = fopen(buf, "w");
    1308           0 :   if ( !md->ctx->debug )
    1309           0 :     log_debug("md debug: can't open %s\n", buf );
    1310             : }
    1311             : 
    1312             : 
    1313             : static void
    1314           0 : md_stop_debug( gcry_md_hd_t md )
    1315             : {
    1316           0 :   if ( md->ctx->debug )
    1317             :     {
    1318           0 :       if ( md->bufpos )
    1319           0 :         md_write ( md, NULL, 0 );
    1320           0 :       fclose (md->ctx->debug);
    1321           0 :       md->ctx->debug = NULL;
    1322             :     }
    1323             : 
    1324             :   {  /* a kludge to pull in the __muldi3 for Solaris */
    1325           0 :     volatile u32 a = (u32)(uintptr_t)md;
    1326           0 :     volatile u64 b = 42;
    1327             :     volatile u64 c;
    1328           0 :     c = a * b;
    1329           0 :     (void)c;
    1330             :   }
    1331           0 : }
    1332             : 
    1333             : 
    1334             : 
    1335             : /*
    1336             :  * Return information about the digest handle.
    1337             :  *  GCRYCTL_IS_SECURE:
    1338             :  *      Returns 1 when the handle works on secured memory
    1339             :  *      otherwise 0 is returned.  There is no error return.
    1340             :  *  GCRYCTL_IS_ALGO_ENABLED:
    1341             :  *     Returns 1 if the algo is enabled for that handle.
    1342             :  *     The algo must be passed as the address of an int.
    1343             :  */
    1344             : gcry_err_code_t
    1345           0 : _gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes)
    1346             : {
    1347           0 :   gcry_err_code_t rc = 0;
    1348             : 
    1349           0 :   switch (cmd)
    1350             :     {
    1351             :     case GCRYCTL_IS_SECURE:
    1352           0 :       *nbytes = h->ctx->flags.secure;
    1353           0 :       break;
    1354             : 
    1355             :     case GCRYCTL_IS_ALGO_ENABLED:
    1356             :       {
    1357             :         GcryDigestEntry *r;
    1358             :         int algo;
    1359             : 
    1360           0 :         if ( !buffer || !nbytes || *nbytes != sizeof (int))
    1361           0 :           rc = GPG_ERR_INV_ARG;
    1362             :         else
    1363             :           {
    1364           0 :             algo = *(int*)buffer;
    1365             : 
    1366           0 :             *nbytes = 0;
    1367           0 :             for(r=h->ctx->list; r; r = r->next ) {
    1368           0 :               if (r->spec->algo == algo)
    1369             :                 {
    1370           0 :                   *nbytes = 1;
    1371           0 :                   break;
    1372             :                 }
    1373             :             }
    1374             :           }
    1375           0 :         break;
    1376             :       }
    1377             : 
    1378             :   default:
    1379           0 :     rc = GPG_ERR_INV_OP;
    1380             :   }
    1381             : 
    1382           0 :   return rc;
    1383             : }
    1384             : 
    1385             : 
    1386             : /* Explicitly initialize this module.  */
    1387             : gcry_err_code_t
    1388          34 : _gcry_md_init (void)
    1389             : {
    1390          34 :   if (fips_mode())
    1391             :     {
    1392             :       /* disable algorithms that are disallowed in fips */
    1393             :       int idx;
    1394             :       gcry_md_spec_t *spec;
    1395             : 
    1396           0 :       for (idx = 0; (spec = digest_list[idx]); idx++)
    1397           0 :         if (!spec->flags.fips)
    1398           0 :           spec->flags.disabled = 1;
    1399             :     }
    1400             : 
    1401          34 :   return 0;
    1402             : }
    1403             : 
    1404             : 
    1405             : int
    1406           0 : _gcry_md_is_secure (gcry_md_hd_t a)
    1407             : {
    1408             :   size_t value;
    1409             : 
    1410           0 :   if (_gcry_md_info (a, GCRYCTL_IS_SECURE, NULL, &value))
    1411           0 :     value = 1; /* It seems to be better to assume secure memory on
    1412             :                   error. */
    1413           0 :   return value;
    1414             : }
    1415             : 
    1416             : 
    1417             : int
    1418           0 : _gcry_md_is_enabled (gcry_md_hd_t a, int algo)
    1419             : {
    1420             :   size_t value;
    1421             : 
    1422           0 :   value = sizeof algo;
    1423           0 :   if (_gcry_md_info (a, GCRYCTL_IS_ALGO_ENABLED, &algo, &value))
    1424           0 :     value = 0;
    1425           0 :   return value;
    1426             : }
    1427             : 
    1428             : 
    1429             : /* Run the selftests for digest algorithm ALGO with optional reporting
    1430             :    function REPORT.  */
    1431             : gpg_error_t
    1432          43 : _gcry_md_selftest (int algo, int extended, selftest_report_func_t report)
    1433             : {
    1434          43 :   gcry_err_code_t ec = 0;
    1435             :   gcry_md_spec_t *spec;
    1436             : 
    1437          43 :   spec = spec_from_algo (algo);
    1438          43 :   if (spec && !spec->flags.disabled && spec->selftest)
    1439          29 :     ec = spec->selftest (algo, extended, report);
    1440             :   else
    1441             :     {
    1442          28 :       ec = (spec && spec->selftest) ? GPG_ERR_DIGEST_ALGO
    1443          14 :         /* */                       : GPG_ERR_NOT_IMPLEMENTED;
    1444          14 :       if (report)
    1445           0 :         report ("digest", algo, "module",
    1446           0 :                 (spec && !spec->flags.disabled)?
    1447             :                 "no selftest available" :
    1448           0 :                 spec? "algorithm disabled" : "algorithm not found");
    1449             :     }
    1450             : 
    1451          43 :   return gpg_error (ec);
    1452             : }

Generated by: LCOV version 1.13