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

          Line data    Source code
       1             : /* hash-common.c - Common code for hash algorithms
       2             :  * Copyright (C) 2008 Free Software Foundation, Inc.
       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             : #ifdef HAVE_STDINT_H
      25             : # include <stdint.h>
      26             : #endif
      27             : 
      28             : #include "g10lib.h"
      29             : #include "hash-common.h"
      30             : 
      31             : 
      32             : /* Run a selftest for hash algorithm ALGO.  If the resulting digest
      33             :    matches EXPECT/EXPECTLEN and everything else is fine as well,
      34             :    return NULL.  If an error occurs, return a static text string
      35             :    describing the error.
      36             : 
      37             :    DATAMODE controls what will be hashed according to this table:
      38             : 
      39             :      0 - Hash the supplied DATA of DATALEN.
      40             :      1 - Hash one million times a 'a'.  DATA and DATALEN are ignored.
      41             : 
      42             : */
      43             : const char *
      44           0 : _gcry_hash_selftest_check_one (int algo,
      45             :                                int datamode, const void *data, size_t datalen,
      46             :                                const void *expect, size_t expectlen)
      47             : {
      48           0 :   const char *result = NULL;
      49           0 :   gcry_error_t err = 0;
      50             :   gcry_md_hd_t hd;
      51             :   unsigned char *digest;
      52             :   char aaa[1000];
      53           0 :   int xof = 0;
      54             : 
      55           0 :   if (_gcry_md_get_algo_dlen (algo) == 0)
      56           0 :     xof = 1;
      57           0 :   else if (_gcry_md_get_algo_dlen (algo) != expectlen)
      58           0 :     return "digest size does not match expected size";
      59             : 
      60           0 :   err = _gcry_md_open (&hd, algo, 0);
      61           0 :   if (err)
      62           0 :     return "gcry_md_open failed";
      63             : 
      64           0 :   switch (datamode)
      65             :     {
      66             :     case 0:
      67           0 :       _gcry_md_write (hd, data, datalen);
      68           0 :       break;
      69             : 
      70             :     case 1: /* Hash one million times an "a". */
      71             :       {
      72             :         int i;
      73             : 
      74             :         /* Write in odd size chunks so that we test the buffering.  */
      75           0 :         memset (aaa, 'a', 1000);
      76           0 :         for (i = 0; i < 1000; i++)
      77           0 :           _gcry_md_write (hd, aaa, 1000);
      78             :       }
      79           0 :       break;
      80             : 
      81             :     default:
      82           0 :       result = "invalid DATAMODE";
      83             :     }
      84             : 
      85           0 :   if (!result)
      86             :     {
      87           0 :       if (!xof)
      88             :         {
      89           0 :           digest = _gcry_md_read (hd, algo);
      90             : 
      91           0 :           if ( memcmp (digest, expect, expectlen) )
      92           0 :             result = "digest mismatch";
      93             :         }
      94             :       else
      95             :         {
      96           0 :           gcry_assert(expectlen <= sizeof(aaa));
      97             : 
      98           0 :           err = _gcry_md_extract (hd, algo, aaa, expectlen);
      99           0 :           if (err)
     100           0 :             result = "error extracting output from XOF";
     101           0 :           else if ( memcmp (aaa, expect, expectlen) )
     102           0 :             result = "digest mismatch";
     103             :         }
     104             :     }
     105             : 
     106           0 :   _gcry_md_close (hd);
     107             : 
     108           0 :   return result;
     109             : }
     110             : 
     111             : 
     112             : /* Common function to write a chunk of data to the transform function
     113             :    of a hash algorithm.  Note that the use of the term "block" does
     114             :    not imply a fixed size block.  Note that we explicitly allow to use
     115             :    this function after the context has been finalized; the result does
     116             :    not have any meaning but writing after finalize is sometimes
     117             :    helpful to mitigate timing attacks. */
     118             : void
     119           0 : _gcry_md_block_write (void *context, const void *inbuf_arg, size_t inlen)
     120             : {
     121           0 :   const unsigned char *inbuf = inbuf_arg;
     122           0 :   gcry_md_block_ctx_t *hd = context;
     123           0 :   unsigned int stack_burn = 0;
     124           0 :   const unsigned int blocksize = hd->blocksize;
     125             :   size_t inblocks;
     126             : 
     127           0 :   if (sizeof(hd->buf) < blocksize)
     128           0 :     BUG();
     129             : 
     130           0 :   if (!hd->bwrite)
     131           0 :     return;
     132             : 
     133           0 :   if (hd->count == blocksize)  /* Flush the buffer. */
     134             :     {
     135           0 :       stack_burn = hd->bwrite (hd, hd->buf, 1);
     136           0 :       _gcry_burn_stack (stack_burn);
     137           0 :       stack_burn = 0;
     138           0 :       hd->count = 0;
     139           0 :       if (!++hd->nblocks)
     140           0 :         hd->nblocks_high++;
     141             :     }
     142           0 :   if (!inbuf)
     143           0 :     return;
     144             : 
     145           0 :   if (hd->count)
     146             :     {
     147           0 :       for (; inlen && hd->count < blocksize; inlen--)
     148           0 :         hd->buf[hd->count++] = *inbuf++;
     149           0 :       _gcry_md_block_write (hd, NULL, 0);
     150           0 :       if (!inlen)
     151           0 :         return;
     152             :     }
     153             : 
     154           0 :   if (inlen >= blocksize)
     155             :     {
     156           0 :       inblocks = inlen / blocksize;
     157           0 :       stack_burn = hd->bwrite (hd, inbuf, inblocks);
     158           0 :       hd->count = 0;
     159           0 :       hd->nblocks_high += (hd->nblocks + inblocks < inblocks);
     160           0 :       hd->nblocks += inblocks;
     161           0 :       inlen -= inblocks * blocksize;
     162           0 :       inbuf += inblocks * blocksize;
     163             :     }
     164           0 :   _gcry_burn_stack (stack_burn);
     165           0 :   for (; inlen && hd->count < blocksize; inlen--)
     166           0 :     hd->buf[hd->count++] = *inbuf++;
     167             : }

Generated by: LCOV version 1.12