1/* hmac.c -  HMAC regression tests
2 *	Copyright (C) 2005 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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21#ifdef HAVE_CONFIG_H
22#include <config.h>
23#endif
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <stdarg.h>
28
29#include "../src/gcrypt.h"
30
31static int verbose;
32static int error_count;
33
34static void
35fail (const char *format, ...)
36{
37  va_list arg_ptr;
38
39  va_start (arg_ptr, format);
40  vfprintf (stderr, format, arg_ptr);
41  va_end (arg_ptr);
42  error_count++;
43}
44
45static void
46die (const char *format, ...)
47{
48  va_list arg_ptr;
49
50  va_start (arg_ptr, format);
51  vfprintf (stderr, format, arg_ptr);
52  va_end (arg_ptr);
53  exit (1);
54}
55
56
57
58static void
59check_one_mac (int algo,
60               const void *key, size_t keylen,
61               const void *data, size_t datalen,
62               const char *expect)
63{
64  gcry_md_hd_t hd;
65  unsigned char *p;
66  int mdlen;
67  int i;
68  gcry_error_t err = 0;
69
70  err = gcry_md_open (&hd, algo, GCRY_MD_FLAG_HMAC);
71  if (err)
72    {
73      fail ("algo %d, gcry_md_open failed: %s\n", algo, gpg_strerror (err));
74      return;
75    }
76
77  mdlen = gcry_md_get_algo_dlen (algo);
78  if (mdlen < 1 || mdlen > 500)
79    {
80      fail ("algo %d, gcry_md_get_algo_dlen failed: %d\n", algo, mdlen);
81      return;
82    }
83
84  err = gcry_md_setkey (hd, key, keylen);
85  if (err)
86    {
87      fail ("algo %d, gcry_md_setkey failed: %s\n", algo, gpg_strerror (err));
88      return;
89    }
90
91  gcry_md_write (hd, data, datalen);
92
93  p = gcry_md_read (hd, 0);
94
95  if (memcmp (p, expect, mdlen))
96    {
97      printf ("computed: ");
98      for (i = 0; i < mdlen; i++)
99	printf ("%02x ", p[i] & 0xFF);
100      printf ("\nexpected: ");
101      for (i = 0; i < mdlen; i++)
102	printf ("%02x ", expect[i] & 0xFF);
103      printf ("\n");
104
105      fail ("algo %d, MAC does not match\n", algo);
106    }
107
108  gcry_md_close (hd);
109}
110
111static void
112check_hmac (void)
113{
114  unsigned char key[128];
115  int i, j;
116
117  if (verbose)
118    fprintf (stderr, "checking FIPS-198a, A.1\n");
119  for (i=0; i < 64; i++)
120    key[i] = i;
121  check_one_mac (GCRY_MD_SHA1, key, 64, "Sample #1", 9,
122                 "\x4f\x4c\xa3\xd5\xd6\x8b\xa7\xcc\x0a\x12"
123                 "\x08\xc9\xc6\x1e\x9c\x5d\xa0\x40\x3c\x0a");
124
125  if (verbose)
126    fprintf (stderr, "checking FIPS-198a, A.2\n");
127  for (i=0, j=0x30; i < 20; i++)
128    key[i] = j++;
129  check_one_mac (GCRY_MD_SHA1, key, 20, "Sample #2", 9,
130                 "\x09\x22\xd3\x40\x5f\xaa\x3d\x19\x4f\x82"
131                 "\xa4\x58\x30\x73\x7d\x5c\xc6\xc7\x5d\x24");
132
133  if (verbose)
134    fprintf (stderr, "checking FIPS-198a, A.3\n");
135  for (i=0, j=0x50; i < 100; i++)
136    key[i] = j++;
137  check_one_mac (GCRY_MD_SHA1, key, 100, "Sample #3", 9,
138                 "\xbc\xf4\x1e\xab\x8b\xb2\xd8\x02\xf3\xd0"
139                 "\x5c\xaf\x7c\xb0\x92\xec\xf8\xd1\xa3\xaa");
140
141  if (verbose)
142    fprintf (stderr, "checking FIPS-198a, A.4\n");
143  for (i=0, j=0x70; i < 49; i++)
144    key[i] = j++;
145  check_one_mac (GCRY_MD_SHA1, key, 49, "Sample #4", 9,
146                 "\x9e\xa8\x86\xef\xe2\x68\xdb\xec\xce\x42"
147                 "\x0c\x75\x24\xdf\x32\xe0\x75\x1a\x2a\x26");
148
149}
150
151int
152main (int argc, char **argv)
153{
154  int debug = 0;
155
156  if (argc > 1 && !strcmp (argv[1], "--verbose"))
157    verbose = 1;
158  else if (argc > 1 && !strcmp (argv[1], "--debug"))
159    verbose = debug = 1;
160
161  if (!gcry_check_version (GCRYPT_VERSION))
162    die ("version mismatch\n");
163
164  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
165  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
166  if (debug)
167    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
168  check_hmac ();
169
170  return error_count ? 1 : 0;
171}
172