Line data Source code
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-int.h"
30 :
31 : static int verbose;
32 : static int error_count;
33 :
34 : static void
35 0 : fail (const char *format, ...)
36 : {
37 : va_list arg_ptr;
38 :
39 0 : va_start (arg_ptr, format);
40 0 : vfprintf (stderr, format, arg_ptr);
41 0 : va_end (arg_ptr);
42 0 : error_count++;
43 0 : }
44 :
45 : static void
46 0 : die (const char *format, ...)
47 : {
48 : va_list arg_ptr;
49 :
50 0 : va_start (arg_ptr, format);
51 0 : vfprintf (stderr, format, arg_ptr);
52 0 : va_end (arg_ptr);
53 0 : exit (1);
54 : }
55 :
56 :
57 :
58 : static void
59 4 : check_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 4 : gcry_error_t err = 0;
69 :
70 4 : err = gcry_md_open (&hd, algo, GCRY_MD_FLAG_HMAC);
71 4 : if (err)
72 : {
73 0 : fail ("algo %d, gcry_md_open failed: %s\n", algo, gpg_strerror (err));
74 0 : return;
75 : }
76 :
77 4 : mdlen = gcry_md_get_algo_dlen (algo);
78 4 : if (mdlen < 1 || mdlen > 500)
79 : {
80 0 : fail ("algo %d, gcry_md_get_algo_dlen failed: %d\n", algo, mdlen);
81 0 : return;
82 : }
83 :
84 4 : err = gcry_md_setkey (hd, key, keylen);
85 4 : if (err)
86 : {
87 0 : fail ("algo %d, gcry_md_setkey failed: %s\n", algo, gpg_strerror (err));
88 0 : return;
89 : }
90 :
91 4 : gcry_md_write (hd, data, datalen);
92 :
93 4 : p = gcry_md_read (hd, 0);
94 :
95 4 : if (memcmp (p, expect, mdlen))
96 : {
97 0 : printf ("computed: ");
98 0 : for (i = 0; i < mdlen; i++)
99 0 : printf ("%02x ", p[i] & 0xFF);
100 0 : printf ("\nexpected: ");
101 0 : for (i = 0; i < mdlen; i++)
102 0 : printf ("%02x ", expect[i] & 0xFF);
103 0 : printf ("\n");
104 :
105 0 : fail ("algo %d, MAC does not match\n", algo);
106 : }
107 :
108 4 : gcry_md_close (hd);
109 : }
110 :
111 : static void
112 1 : check_hmac (void)
113 : {
114 : unsigned char key[128];
115 : int i, j;
116 :
117 1 : if (verbose)
118 0 : fprintf (stderr, "checking FIPS-198a, A.1\n");
119 65 : for (i=0; i < 64; i++)
120 64 : key[i] = i;
121 1 : 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 1 : if (verbose)
126 0 : fprintf (stderr, "checking FIPS-198a, A.2\n");
127 21 : for (i=0, j=0x30; i < 20; i++)
128 20 : key[i] = j++;
129 1 : 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 1 : if (verbose)
134 0 : fprintf (stderr, "checking FIPS-198a, A.3\n");
135 101 : for (i=0, j=0x50; i < 100; i++)
136 100 : key[i] = j++;
137 1 : 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 1 : if (verbose)
142 0 : fprintf (stderr, "checking FIPS-198a, A.4\n");
143 50 : for (i=0, j=0x70; i < 49; i++)
144 49 : key[i] = j++;
145 1 : 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 1 : }
150 :
151 :
152 : static void
153 1 : check_hmac_multi (void)
154 : {
155 : gpg_error_t err;
156 : unsigned char key[128];
157 1 : const char msg[] = "Sample #1";
158 1 : const char mac[] = ("\x4f\x4c\xa3\xd5\xd6\x8b\xa7\xcc\x0a\x12"
159 : "\x08\xc9\xc6\x1e\x9c\x5d\xa0\x40\x3c\x0a");
160 : gcry_buffer_t iov[4];
161 : char digest[64];
162 : int i;
163 : int algo;
164 : int maclen;
165 :
166 1 : if (verbose)
167 0 : fprintf (stderr, "checking HMAC using multiple buffers\n");
168 65 : for (i=0; i < 64; i++)
169 64 : key[i] = i;
170 :
171 1 : memset (iov, 0, sizeof iov);
172 1 : iov[0].data = key;
173 1 : iov[0].len = 64;
174 1 : iov[1].data = (void*)msg;
175 1 : iov[1].off = 0;
176 1 : iov[1].len = 3;
177 1 : iov[2].data = (void*)msg;
178 1 : iov[2].off = 3;
179 1 : iov[2].len = 1;
180 1 : iov[3].data = (void*)msg;
181 1 : iov[3].off = 4;
182 1 : iov[3].len = 5;
183 :
184 1 : algo = GCRY_MD_SHA1;
185 1 : maclen = gcry_md_get_algo_dlen (algo);
186 1 : err = gcry_md_hash_buffers (algo, GCRY_MD_FLAG_HMAC, digest, iov, 4);
187 1 : if (err)
188 : {
189 0 : fail ("gcry_md_hash_buffers failed: %s\n", algo, gpg_strerror (err));
190 1 : return;
191 : }
192 :
193 1 : if (memcmp (digest, mac, maclen))
194 : {
195 0 : printf ("computed: ");
196 0 : for (i = 0; i < maclen; i++)
197 0 : printf ("%02x ", digest[i] & 0xFF);
198 0 : printf ("\nexpected: ");
199 0 : for (i = 0; i < maclen; i++)
200 0 : printf ("%02x ", mac[i] & 0xFF);
201 0 : printf ("\n");
202 :
203 0 : fail ("gcry_md_hash_buffers, algo %d, MAC does not match\n", algo);
204 : }
205 : }
206 :
207 :
208 : int
209 1 : main (int argc, char **argv)
210 : {
211 1 : int debug = 0;
212 :
213 1 : if (argc > 1 && !strcmp (argv[1], "--verbose"))
214 0 : verbose = 1;
215 1 : else if (argc > 1 && !strcmp (argv[1], "--debug"))
216 0 : verbose = debug = 1;
217 :
218 1 : if (!gcry_check_version (GCRYPT_VERSION))
219 0 : die ("version mismatch\n");
220 :
221 1 : gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
222 1 : gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
223 1 : if (debug)
224 0 : gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
225 1 : check_hmac ();
226 1 : check_hmac_multi ();
227 :
228 1 : return error_count ? 1 : 0;
229 : }
|