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*/
43const char *
44_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  const char *result = NULL;
49  gcry_error_t err = 0;
50  gcry_md_hd_t hd;
51  unsigned char *digest;
52
53  if (_gcry_md_get_algo_dlen (algo) != expectlen)
54    return "digest size does not match expected size";
55
56  err = _gcry_md_open (&hd, algo, 0);
57  if (err)
58    return "gcry_md_open failed";
59
60  switch (datamode)
61    {
62    case 0:
63      _gcry_md_write (hd, data, datalen);
64      break;
65
66    case 1: /* Hash one million times an "a". */
67      {
68        char aaa[1000];
69        int i;
70
71        /* Write in odd size chunks so that we test the buffering.  */
72        memset (aaa, 'a', 1000);
73        for (i = 0; i < 1000; i++)
74          _gcry_md_write (hd, aaa, 1000);
75      }
76      break;
77
78    default:
79      result = "invalid DATAMODE";
80    }
81
82  if (!result)
83    {
84      digest = _gcry_md_read (hd, algo);
85
86      if ( memcmp (digest, expect, expectlen) )
87        result = "digest mismatch";
88    }
89
90  _gcry_md_close (hd);
91
92  return result;
93}
94