Added hmac test
[libgcrypt.git] / tests / hmac.c
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
31 static int verbose;
32 static int error_count;
33
34 static void
35 fail (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
45 static void
46 die (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
58 static void
59 check_one_mac (int algo,
60                void *key, size_t keylen,
61                void *data, size_t datalen,
62                char *expect)
63 {
64   gcry_md_hd_t hd;
65   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, grcy_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, grcy_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, grcy_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
111 static void
112 check_hmac (void)
113 {
114   unsigned char key[64];
115   int i, j;
116
117   /* FIPS 198a, A.1 */
118   for (i=0; i < 64; i++)
119     key[i] = i;
120   check_one_mac (GCRY_MD_SHA1, key, 64, "Sample #1", 9,
121                  "\x4f\x4c\xa3\xd5\xd6\x8b\xa7\xcc\x0a\x12"
122                  "\x08\xc9\xc6\x1e\x9c\x5d\xa0\x40\x3c\x0a");
123
124   /* FIPS 198a, A.2 */
125   for (i=0, j=0x30; i < 20; i++)
126     key[i] = j++;
127   check_one_mac (GCRY_MD_SHA1, key, 20, "Sample #2", 9,
128                  "\x09\x22\xd3\x40\x5f\xaa\x3d\x19\x4f\x82"
129                  "\xa4\x58\x30\x73\x7d\x5c\xc6\xc7\x5d\x24");
130
131 }
132
133 int
134 main (int argc, char **argv)
135 {
136   int debug = 0;
137
138   if (argc > 1 && !strcmp (argv[1], "--verbose"))
139     verbose = 1;
140   else if (argc > 1 && !strcmp (argv[1], "--debug"))
141     verbose = debug = 1;
142
143   if (!gcry_check_version (GCRYPT_VERSION))
144     die ("version mismatch\n");
145
146   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
147   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
148   if (debug)
149     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
150   check_hmac ();
151
152   return error_count ? 1 : 0;
153 }