xref: /openbsd/regress/lib/libcrypto/hmac/hmactest.c (revision 771fbea0)
1 /*	$OpenBSD: hmactest.c,v 1.4 2018/07/17 17:06:49 tb Exp $	*/
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  *
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  *
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  *
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  *
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58 
59 #include <stdio.h>
60 #include <string.h>
61 #include <stdlib.h>
62 
63 #include <openssl/hmac.h>
64 #ifndef OPENSSL_NO_MD5
65 #include <openssl/md5.h>
66 #endif
67 
68 #ifndef OPENSSL_NO_MD5
69 static struct test_st {
70 	unsigned char key[16];
71 	int key_len;
72 	unsigned char data[64];
73 	int data_len;
74 	unsigned char *digest;
75 } test[8] = {
76 	{	"",
77 		0,
78 		"More text test vectors to stuff up EBCDIC machines :-)",
79 		54,
80 		(unsigned char *)"e9139d1e6ee064ef8cf514fc7dc83e86",
81 	},
82 	{	{0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
83 		 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,},
84 		16,
85 		"Hi There",
86 		8,
87 		(unsigned char *)"9294727a3638bb1c13f48ef8158bfc9d",
88 	},
89 	{	"Jefe",
90 		4,
91 		"what do ya want for nothing?",
92 		28,
93 		(unsigned char *)"750c783e6ab0b503eaa86e310a5db738",
94 	},
95 	{	{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
96 		 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,},
97 		16,
98 		{0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
99 		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
100 		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
101 		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
102 		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
103 		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
104 		 0xdd,0xdd},
105 		50,
106 		(unsigned char *)"56be34521d144c88dbb8c733f0e8b3f6",
107 	},
108 	{	"",
109 		0,
110 		"My test data",
111 		12,
112 		(unsigned char *)"61afdecb95429ef494d61fdee15990cabf0826fc"
113 	},
114 	{	"",
115 		0,
116 		"My test data",
117 		12,
118 		(unsigned char *)"2274b195d90ce8e03406f4b526a47e0787a88a65479938f1a5baa3ce0f079776"
119 	},
120 	{	"123456",
121 		6,
122 		"My test data",
123 		12,
124 		(unsigned char *)"bab53058ae861a7f191abe2d0145cbb123776a6369ee3f9d79ce455667e411dd"
125 	},
126 	{	"12345",
127 		5,
128 		"My test data again",
129 		12,
130 		(unsigned char *)"7dbe8c764c068e3bcd6e6b0fbcd5e6fc197b15bb"
131 	}
132 };
133 #endif
134 
135 static char *pt(unsigned char *md, unsigned int len);
136 
137 int
138 main(int argc, char *argv[])
139 {
140 #ifndef OPENSSL_NO_MD5
141 	int i;
142 	char *p;
143 #endif
144 	int err = 0;
145 	HMAC_CTX ctx, ctx2;
146 	unsigned char buf[EVP_MAX_MD_SIZE];
147 	unsigned int len;
148 
149 #ifdef OPENSSL_NO_MD5
150 	printf("test skipped: MD5 disabled\n");
151 #else
152 
153 	for (i = 0; i < 4; i++) {
154 		p = pt(HMAC(EVP_md5(),
155 			test[i].key, test[i].key_len,
156 			test[i].data, test[i].data_len, NULL, NULL),
157 			MD5_DIGEST_LENGTH);
158 
159 		if (strcmp(p, (char *)test[i].digest) != 0) {
160 			printf("error calculating HMAC on %d entry'\n", i);
161 			printf("got %s instead of %s\n", p, test[i].digest);
162 			err++;
163 		} else
164 			printf("test %d ok\n", i);
165 	}
166 #endif /* OPENSSL_NO_MD5 */
167 
168 /* test4 */
169 	HMAC_CTX_init(&ctx);
170 	if (HMAC_Init_ex(&ctx, NULL, 0, NULL, NULL)) {
171 		printf("Should fail to initialise HMAC with empty MD and key (test 4)\n");
172 		err++;
173 		goto test5;
174 	}
175 	if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
176 		printf("Should fail HMAC_Update with ctx not set up (test 4)\n");
177 		err++;
178 		goto test5;
179 	}
180 	if (HMAC_Init_ex(&ctx, NULL, 0, EVP_sha1(), NULL)) {
181 		printf("Should fail to initialise HMAC with empty key (test 4)\n");
182 		err++;
183 		goto test5;
184 	}
185 	if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
186 		printf("Should fail HMAC_Update with ctx not set up (test 4)\n");
187 		err++;
188 		goto test5;
189 	}
190 	printf("test 4 ok\n");
191  test5:
192 	HMAC_CTX_cleanup(&ctx);
193 	HMAC_CTX_init(&ctx);
194 	if (HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, NULL, NULL)) {
195 		printf("Should fail to initialise HMAC with empty MD (test 5)\n");
196 		err++;
197 		goto test6;
198 	}
199 	if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
200 		printf("Should fail HMAC_Update with ctx not set up (test 5)\n");
201 		err++;
202 		goto test6;
203 	}
204 	if (HMAC_Init_ex(&ctx, test[4].key, -1, EVP_sha1(), NULL)) {
205 		printf("Should fail to initialise HMAC with invalid key len(test 5)\n");
206 		err++;
207 		goto test6;
208 	}
209 	if (!HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, EVP_sha1(), NULL)) {
210 		printf("Failed to initialise HMAC (test 5)\n");
211 		err++;
212 		goto test6;
213 	}
214 	if (!HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
215 		printf("Error updating HMAC with data (test 5)\n");
216 		err++;
217 		goto test6;
218 	}
219 	if (!HMAC_Final(&ctx, buf, &len)) {
220 		printf("Error finalising data (test 5)\n");
221 		err++;
222 		goto test6;
223 	}
224 	p = pt(buf, len);
225 	if (strcmp(p, (char *)test[4].digest) != 0) {
226 		printf("Error calculating interim HMAC on test 5\n");
227 		printf("got %s instead of %s\n", p, test[4].digest);
228 		err++;
229 		goto test6;
230 	}
231 	if (HMAC_Init_ex(&ctx, NULL, 0, EVP_sha256(), NULL)) {
232 		printf("Should disallow changing MD without a new key (test 5)\n");
233 		err++;
234 		goto test6;
235 	}
236 	if (!HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, EVP_sha256(), NULL)) {
237 		printf("Failed to reinitialise HMAC (test 5)\n");
238 		err++;
239 		goto test6;
240 	}
241 	if (!HMAC_Update(&ctx, test[5].data, test[5].data_len)) {
242 		printf("Error updating HMAC with data (sha256) (test 5)\n");
243 		err++;
244 		goto test6;
245 	}
246 	if (!HMAC_Final(&ctx, buf, &len)) {
247 		printf("Error finalising data (sha256) (test 5)\n");
248 		err++;
249 		goto test6;
250 	}
251 	p = pt(buf, len);
252 	if (strcmp(p, (char *)test[5].digest) != 0) {
253 		printf("Error calculating 2nd interim HMAC on test 5\n");
254 		printf("got %s instead of %s\n", p, test[5].digest);
255 		err++;
256 		goto test6;
257 	}
258 	if (!HMAC_Init_ex(&ctx, test[6].key, test[6].key_len, NULL, NULL)) {
259 		printf("Failed to reinitialise HMAC with key (test 5)\n");
260 		err++;
261 		goto test6;
262 	}
263 	if (!HMAC_Update(&ctx, test[6].data, test[6].data_len)) {
264 		printf("Error updating HMAC with data (new key) (test 5)\n");
265 		err++;
266 		goto test6;
267 	}
268 	if (!HMAC_Final(&ctx, buf, &len)) {
269 		printf("Error finalising data (new key) (test 5)\n");
270 		err++;
271 		goto test6;
272 	}
273 	p = pt(buf, len);
274 	if (strcmp(p, (char *)test[6].digest) != 0) {
275 		printf("error calculating HMAC on test 5\n");
276 		printf("got %s instead of %s\n", p, test[6].digest);
277 		err++;
278 	} else {
279 		printf("test 5 ok\n");
280 	}
281  test6:
282 	HMAC_CTX_cleanup(&ctx);
283 	HMAC_CTX_init(&ctx);
284 	if (!HMAC_Init_ex(&ctx, test[7].key, test[7].key_len, EVP_sha1(), NULL)) {
285 		printf("Failed to initialise HMAC (test 6)\n");
286 		err++;
287 		goto end;
288 	}
289 	if (!HMAC_Update(&ctx, test[7].data, test[7].data_len)) {
290 		printf("Error updating HMAC with data (test 6)\n");
291 		err++;
292 		goto end;
293 	}
294 	if (!HMAC_CTX_copy(&ctx2, &ctx)) {
295 		printf("Failed to copy HMAC_CTX (test 6)\n");
296 		err++;
297 		goto end;
298 	}
299 	if (!HMAC_Final(&ctx2, buf, &len)) {
300 		printf("Error finalising data (test 6)\n");
301 		err++;
302 		goto end;
303 	}
304 	p = pt(buf, len);
305 	if (strcmp(p, (char *)test[7].digest) != 0) {
306 		printf("Error calculating HMAC on test 6\n");
307 		printf("got %s instead of %s\n", p, test[7].digest);
308 		err++;
309 	} else {
310 		printf("test 6 ok\n");
311 	}
312 end:
313 	HMAC_CTX_cleanup(&ctx);
314 	exit(err);
315 	return(0);
316 }
317 
318 #ifndef OPENSSL_NO_MD5
319 static char *
320 pt(unsigned char *md, unsigned int len)
321 {
322 	unsigned int i;
323 	static char buf[80];
324 
325 	for (i = 0; i < len; i++)
326 		snprintf(buf + i * 2, sizeof(buf) - i * 2, "%02x", md[i]);
327 	return(buf);
328 }
329 #endif
330