api: New function gcry_get_config.
[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 #define PGM "hmac"
30 #include "t-common.h"
31
32
33 static void
34 check_one_mac (int algo,
35                const void *key, size_t keylen,
36                const void *data, size_t datalen,
37                const char *expect)
38 {
39   gcry_md_hd_t hd;
40   unsigned char *p;
41   int mdlen;
42   int i;
43   gcry_error_t err = 0;
44
45   err = gcry_md_open (&hd, algo, GCRY_MD_FLAG_HMAC);
46   if (err)
47     {
48       fail ("algo %d, gcry_md_open failed: %s\n", algo, gpg_strerror (err));
49       return;
50     }
51
52   mdlen = gcry_md_get_algo_dlen (algo);
53   if (mdlen < 1 || mdlen > 500)
54     {
55       fail ("algo %d, gcry_md_get_algo_dlen failed: %d\n", algo, mdlen);
56       return;
57     }
58
59   err = gcry_md_setkey (hd, key, keylen);
60   if (err)
61     {
62       fail ("algo %d, gcry_md_setkey failed: %s\n", algo, gpg_strerror (err));
63       return;
64     }
65
66   gcry_md_write (hd, data, datalen);
67
68   p = gcry_md_read (hd, 0);
69
70   if (memcmp (p, expect, mdlen))
71     {
72       printf ("computed: ");
73       for (i = 0; i < mdlen; i++)
74         printf ("%02x ", p[i] & 0xFF);
75       printf ("\nexpected: ");
76       for (i = 0; i < mdlen; i++)
77         printf ("%02x ", expect[i] & 0xFF);
78       printf ("\n");
79
80       fail ("algo %d, MAC does not match\n", algo);
81     }
82
83   gcry_md_close (hd);
84 }
85
86 static void
87 check_hmac (void)
88 {
89   unsigned char key[128];
90   int i, j;
91
92   if (verbose)
93     fprintf (stderr, "checking FIPS-198a, A.1\n");
94   for (i=0; i < 64; i++)
95     key[i] = i;
96   check_one_mac (GCRY_MD_SHA1, key, 64, "Sample #1", 9,
97                  "\x4f\x4c\xa3\xd5\xd6\x8b\xa7\xcc\x0a\x12"
98                  "\x08\xc9\xc6\x1e\x9c\x5d\xa0\x40\x3c\x0a");
99
100   if (verbose)
101     fprintf (stderr, "checking FIPS-198a, A.2\n");
102   for (i=0, j=0x30; i < 20; i++)
103     key[i] = j++;
104   check_one_mac (GCRY_MD_SHA1, key, 20, "Sample #2", 9,
105                  "\x09\x22\xd3\x40\x5f\xaa\x3d\x19\x4f\x82"
106                  "\xa4\x58\x30\x73\x7d\x5c\xc6\xc7\x5d\x24");
107
108   if (verbose)
109     fprintf (stderr, "checking FIPS-198a, A.3\n");
110   for (i=0, j=0x50; i < 100; i++)
111     key[i] = j++;
112   check_one_mac (GCRY_MD_SHA1, key, 100, "Sample #3", 9,
113                  "\xbc\xf4\x1e\xab\x8b\xb2\xd8\x02\xf3\xd0"
114                  "\x5c\xaf\x7c\xb0\x92\xec\xf8\xd1\xa3\xaa");
115
116   if (verbose)
117     fprintf (stderr, "checking FIPS-198a, A.4\n");
118   for (i=0, j=0x70; i < 49; i++)
119     key[i] = j++;
120   check_one_mac (GCRY_MD_SHA1, key, 49, "Sample #4", 9,
121                  "\x9e\xa8\x86\xef\xe2\x68\xdb\xec\xce\x42"
122                  "\x0c\x75\x24\xdf\x32\xe0\x75\x1a\x2a\x26");
123
124 }
125
126
127 static void
128 check_hmac_multi (void)
129 {
130   gpg_error_t err;
131   unsigned char key[128];
132   const char msg[] = "Sample #1";
133   const char mac[] = ("\x4f\x4c\xa3\xd5\xd6\x8b\xa7\xcc\x0a\x12"
134                       "\x08\xc9\xc6\x1e\x9c\x5d\xa0\x40\x3c\x0a");
135   gcry_buffer_t iov[4];
136   char digest[64];
137   int i;
138   int algo;
139   int maclen;
140
141   if (verbose)
142     fprintf (stderr, "checking HMAC using multiple buffers\n");
143   for (i=0; i < 64; i++)
144     key[i] = i;
145
146   memset (iov, 0, sizeof iov);
147   iov[0].data = key;
148   iov[0].len = 64;
149   iov[1].data = (void*)msg;
150   iov[1].off = 0;
151   iov[1].len = 3;
152   iov[2].data = (void*)msg;
153   iov[2].off = 3;
154   iov[2].len = 1;
155   iov[3].data = (void*)msg;
156   iov[3].off = 4;
157   iov[3].len = 5;
158
159   algo = GCRY_MD_SHA1;
160   maclen = gcry_md_get_algo_dlen (algo);
161   err = gcry_md_hash_buffers (algo, GCRY_MD_FLAG_HMAC, digest, iov, 4);
162   if (err)
163     {
164       fail ("gcry_md_hash_buffers failed for algo %d: %s\n",
165             algo, gpg_strerror (err));
166       return;
167     }
168
169   if (memcmp (digest, mac, maclen))
170     {
171       printf ("computed: ");
172       for (i = 0; i < maclen; i++)
173         printf ("%02x ", digest[i] & 0xFF);
174       printf ("\nexpected: ");
175       for (i = 0; i < maclen; i++)
176         printf ("%02x ", mac[i] & 0xFF);
177       printf ("\n");
178
179       fail ("gcry_md_hash_buffers, algo %d, MAC does not match\n", algo);
180     }
181 }
182
183
184 int
185 main (int argc, char **argv)
186 {
187   if (argc > 1 && !strcmp (argv[1], "--verbose"))
188     verbose = 1;
189   else if (argc > 1 && !strcmp (argv[1], "--debug"))
190     verbose = debug = 1;
191
192   if (!gcry_check_version (GCRYPT_VERSION))
193     die ("version mismatch\n");
194
195   xgcry_control (GCRYCTL_DISABLE_SECMEM, 0);
196   xgcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
197   if (debug)
198     xgcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
199   check_hmac ();
200   check_hmac_multi ();
201
202   return error_count ? 1 : 0;
203 }