xref: /openbsd-src/regress/lib/libcrypto/hmac/hmactest.c (revision e2b8045fcc9d094c01f8ebdfa9553a0bb83c5bc9)
1*e2b8045fStb /*	$OpenBSD: hmactest.c,v 1.8 2024/05/30 17:01:38 tb Exp $	*/
23c6bd008Smiod /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
33c6bd008Smiod  * All rights reserved.
43c6bd008Smiod  *
53c6bd008Smiod  * This package is an SSL implementation written
63c6bd008Smiod  * by Eric Young (eay@cryptsoft.com).
73c6bd008Smiod  * The implementation was written so as to conform with Netscapes SSL.
83c6bd008Smiod  *
93c6bd008Smiod  * This library is free for commercial and non-commercial use as long as
103c6bd008Smiod  * the following conditions are aheared to.  The following conditions
113c6bd008Smiod  * apply to all code found in this distribution, be it the RC4, RSA,
123c6bd008Smiod  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
133c6bd008Smiod  * included with this distribution is covered by the same copyright terms
143c6bd008Smiod  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
153c6bd008Smiod  *
163c6bd008Smiod  * Copyright remains Eric Young's, and as such any Copyright notices in
173c6bd008Smiod  * the code are not to be removed.
183c6bd008Smiod  * If this package is used in a product, Eric Young should be given attribution
193c6bd008Smiod  * as the author of the parts of the library used.
203c6bd008Smiod  * This can be in the form of a textual message at program startup or
213c6bd008Smiod  * in documentation (online or textual) provided with the package.
223c6bd008Smiod  *
233c6bd008Smiod  * Redistribution and use in source and binary forms, with or without
243c6bd008Smiod  * modification, are permitted provided that the following conditions
253c6bd008Smiod  * are met:
263c6bd008Smiod  * 1. Redistributions of source code must retain the copyright
273c6bd008Smiod  *    notice, this list of conditions and the following disclaimer.
283c6bd008Smiod  * 2. Redistributions in binary form must reproduce the above copyright
293c6bd008Smiod  *    notice, this list of conditions and the following disclaimer in the
303c6bd008Smiod  *    documentation and/or other materials provided with the distribution.
313c6bd008Smiod  * 3. All advertising materials mentioning features or use of this software
323c6bd008Smiod  *    must display the following acknowledgement:
333c6bd008Smiod  *    "This product includes cryptographic software written by
343c6bd008Smiod  *     Eric Young (eay@cryptsoft.com)"
353c6bd008Smiod  *    The word 'cryptographic' can be left out if the rouines from the library
363c6bd008Smiod  *    being used are not cryptographic related :-).
373c6bd008Smiod  * 4. If you include any Windows specific code (or a derivative thereof) from
383c6bd008Smiod  *    the apps directory (application code) you must include an acknowledgement:
393c6bd008Smiod  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
403c6bd008Smiod  *
413c6bd008Smiod  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
423c6bd008Smiod  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
433c6bd008Smiod  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
443c6bd008Smiod  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
453c6bd008Smiod  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
463c6bd008Smiod  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
473c6bd008Smiod  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
483c6bd008Smiod  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
493c6bd008Smiod  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
503c6bd008Smiod  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
513c6bd008Smiod  * SUCH DAMAGE.
523c6bd008Smiod  *
533c6bd008Smiod  * The licence and distribution terms for any publically available version or
543c6bd008Smiod  * derivative of this code cannot be changed.  i.e. this code cannot simply be
553c6bd008Smiod  * copied and put under another distribution licence
563c6bd008Smiod  * [including the GNU Public Licence.]
573c6bd008Smiod  */
583c6bd008Smiod 
593c6bd008Smiod #include <stdio.h>
603c6bd008Smiod #include <string.h>
613c6bd008Smiod #include <stdlib.h>
623c6bd008Smiod 
633c6bd008Smiod #include <openssl/hmac.h>
643c6bd008Smiod #ifndef OPENSSL_NO_MD5
653c6bd008Smiod #include <openssl/md5.h>
663c6bd008Smiod #endif
673c6bd008Smiod 
683c6bd008Smiod #ifndef OPENSSL_NO_MD5
69145d9b3fSinoguchi static struct test_st {
703c6bd008Smiod 	unsigned char key[16];
713c6bd008Smiod 	int key_len;
723c6bd008Smiod 	unsigned char data[64];
733c6bd008Smiod 	int data_len;
743c6bd008Smiod 	unsigned char *digest;
75145d9b3fSinoguchi } test[8] = {
763c6bd008Smiod 	{	"",
773c6bd008Smiod 		0,
783c6bd008Smiod 		"More text test vectors to stuff up EBCDIC machines :-)",
793c6bd008Smiod 		54,
803c6bd008Smiod 		(unsigned char *)"e9139d1e6ee064ef8cf514fc7dc83e86",
81145d9b3fSinoguchi 	},
82145d9b3fSinoguchi 	{	{0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
833c6bd008Smiod 		 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,},
843c6bd008Smiod 		16,
853c6bd008Smiod 		"Hi There",
863c6bd008Smiod 		8,
873c6bd008Smiod 		(unsigned char *)"9294727a3638bb1c13f48ef8158bfc9d",
88145d9b3fSinoguchi 	},
89145d9b3fSinoguchi 	{	"Jefe",
903c6bd008Smiod 		4,
913c6bd008Smiod 		"what do ya want for nothing?",
923c6bd008Smiod 		28,
933c6bd008Smiod 		(unsigned char *)"750c783e6ab0b503eaa86e310a5db738",
94145d9b3fSinoguchi 	},
95145d9b3fSinoguchi 	{	{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
963c6bd008Smiod 		 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,},
973c6bd008Smiod 		16,
983c6bd008Smiod 		{0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
993c6bd008Smiod 		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
1003c6bd008Smiod 		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
1013c6bd008Smiod 		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
1023c6bd008Smiod 		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
1033c6bd008Smiod 		 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
1043c6bd008Smiod 		 0xdd,0xdd},
1053c6bd008Smiod 		50,
1063c6bd008Smiod 		(unsigned char *)"56be34521d144c88dbb8c733f0e8b3f6",
1073c6bd008Smiod 	},
108145d9b3fSinoguchi 	{	"",
109145d9b3fSinoguchi 		0,
110145d9b3fSinoguchi 		"My test data",
111145d9b3fSinoguchi 		12,
112145d9b3fSinoguchi 		(unsigned char *)"61afdecb95429ef494d61fdee15990cabf0826fc"
113145d9b3fSinoguchi 	},
114145d9b3fSinoguchi 	{	"",
115145d9b3fSinoguchi 		0,
116145d9b3fSinoguchi 		"My test data",
117145d9b3fSinoguchi 		12,
118145d9b3fSinoguchi 		(unsigned char *)"2274b195d90ce8e03406f4b526a47e0787a88a65479938f1a5baa3ce0f079776"
119145d9b3fSinoguchi 	},
120145d9b3fSinoguchi 	{	"123456",
121145d9b3fSinoguchi 		6,
122145d9b3fSinoguchi 		"My test data",
123145d9b3fSinoguchi 		12,
124145d9b3fSinoguchi 		(unsigned char *)"bab53058ae861a7f191abe2d0145cbb123776a6369ee3f9d79ce455667e411dd"
125145d9b3fSinoguchi 	},
126145d9b3fSinoguchi 	{	"12345",
127145d9b3fSinoguchi 		5,
128145d9b3fSinoguchi 		"My test data again",
129145d9b3fSinoguchi 		12,
130145d9b3fSinoguchi 		(unsigned char *)"7dbe8c764c068e3bcd6e6b0fbcd5e6fc197b15bb"
131145d9b3fSinoguchi 	}
1323c6bd008Smiod };
1333c6bd008Smiod #endif
1343c6bd008Smiod 
135145d9b3fSinoguchi static char *pt(unsigned char *md, unsigned int len);
136145d9b3fSinoguchi 
137145d9b3fSinoguchi int
main(int argc,char * argv[])138145d9b3fSinoguchi main(int argc, char *argv[])
1393c6bd008Smiod {
1403c6bd008Smiod #ifndef OPENSSL_NO_MD5
1413c6bd008Smiod 	int i;
1423c6bd008Smiod 	char *p;
1433c6bd008Smiod #endif
1443c6bd008Smiod 	int err = 0;
1451c94e884Stb 	HMAC_CTX *ctx = NULL, *ctx2 = NULL;
146145d9b3fSinoguchi 	unsigned char buf[EVP_MAX_MD_SIZE];
147145d9b3fSinoguchi 	unsigned int len;
1483c6bd008Smiod 
1493c6bd008Smiod #ifdef OPENSSL_NO_MD5
1503c6bd008Smiod 	printf("test skipped: MD5 disabled\n");
1513c6bd008Smiod #else
1523c6bd008Smiod 
153145d9b3fSinoguchi 	for (i = 0; i < 4; i++) {
1543c6bd008Smiod 		p = pt(HMAC(EVP_md5(),
1553c6bd008Smiod 			test[i].key, test[i].key_len,
156*e2b8045fStb 			test[i].data, test[i].data_len, buf, NULL),
157145d9b3fSinoguchi 			MD5_DIGEST_LENGTH);
1583c6bd008Smiod 
159145d9b3fSinoguchi 		if (strcmp(p, (char *)test[i].digest) != 0) {
1603c6bd008Smiod 			printf("error calculating HMAC on %d entry'\n", i);
1613c6bd008Smiod 			printf("got %s instead of %s\n", p, test[i].digest);
1623c6bd008Smiod 			err++;
163145d9b3fSinoguchi 		} else
1643c6bd008Smiod 			printf("test %d ok\n", i);
1653c6bd008Smiod 	}
1663c6bd008Smiod #endif /* OPENSSL_NO_MD5 */
167145d9b3fSinoguchi 
168145d9b3fSinoguchi /* test4 */
1691c94e884Stb 	if ((ctx = HMAC_CTX_new()) == NULL) {
1701c94e884Stb 		printf("HMAC_CTX_init failed (test 4)\n");
1711c94e884Stb 		exit(1);
1721c94e884Stb 	}
1731c94e884Stb 	if (HMAC_Init_ex(ctx, NULL, 0, NULL, NULL)) {
174145d9b3fSinoguchi 		printf("Should fail to initialise HMAC with empty MD and key (test 4)\n");
175145d9b3fSinoguchi 		err++;
176145d9b3fSinoguchi 		goto test5;
177145d9b3fSinoguchi 	}
1781c94e884Stb 	if (HMAC_Update(ctx, test[4].data, test[4].data_len)) {
179145d9b3fSinoguchi 		printf("Should fail HMAC_Update with ctx not set up (test 4)\n");
180145d9b3fSinoguchi 		err++;
181145d9b3fSinoguchi 		goto test5;
182145d9b3fSinoguchi 	}
1831c94e884Stb 	if (HMAC_Init_ex(ctx, NULL, 0, EVP_sha1(), NULL)) {
184145d9b3fSinoguchi 		printf("Should fail to initialise HMAC with empty key (test 4)\n");
185145d9b3fSinoguchi 		err++;
186145d9b3fSinoguchi 		goto test5;
187145d9b3fSinoguchi 	}
1881c94e884Stb 	if (HMAC_Update(ctx, test[4].data, test[4].data_len)) {
189145d9b3fSinoguchi 		printf("Should fail HMAC_Update with ctx not set up (test 4)\n");
190145d9b3fSinoguchi 		err++;
191145d9b3fSinoguchi 		goto test5;
192145d9b3fSinoguchi 	}
193145d9b3fSinoguchi 	printf("test 4 ok\n");
194145d9b3fSinoguchi  test5:
19563f7f39aStb 	HMAC_CTX_reset(ctx);
1961c94e884Stb 	if (HMAC_Init_ex(ctx, test[4].key, test[4].key_len, NULL, NULL)) {
197145d9b3fSinoguchi 		printf("Should fail to initialise HMAC with empty MD (test 5)\n");
198145d9b3fSinoguchi 		err++;
199145d9b3fSinoguchi 		goto test6;
200145d9b3fSinoguchi 	}
2011c94e884Stb 	if (HMAC_Update(ctx, test[4].data, test[4].data_len)) {
202145d9b3fSinoguchi 		printf("Should fail HMAC_Update with ctx not set up (test 5)\n");
203145d9b3fSinoguchi 		err++;
204145d9b3fSinoguchi 		goto test6;
205145d9b3fSinoguchi 	}
2061c94e884Stb 	if (HMAC_Init_ex(ctx, test[4].key, -1, EVP_sha1(), NULL)) {
207145d9b3fSinoguchi 		printf("Should fail to initialise HMAC with invalid key len(test 5)\n");
208145d9b3fSinoguchi 		err++;
209145d9b3fSinoguchi 		goto test6;
210145d9b3fSinoguchi 	}
2111c94e884Stb 	if (!HMAC_Init_ex(ctx, test[4].key, test[4].key_len, EVP_sha1(), NULL)) {
212145d9b3fSinoguchi 		printf("Failed to initialise HMAC (test 5)\n");
213145d9b3fSinoguchi 		err++;
214145d9b3fSinoguchi 		goto test6;
215145d9b3fSinoguchi 	}
2161c94e884Stb 	if (!HMAC_Update(ctx, test[4].data, test[4].data_len)) {
217145d9b3fSinoguchi 		printf("Error updating HMAC with data (test 5)\n");
218145d9b3fSinoguchi 		err++;
219145d9b3fSinoguchi 		goto test6;
220145d9b3fSinoguchi 	}
2211c94e884Stb 	if (!HMAC_Final(ctx, buf, &len)) {
222145d9b3fSinoguchi 		printf("Error finalising data (test 5)\n");
223145d9b3fSinoguchi 		err++;
224145d9b3fSinoguchi 		goto test6;
225145d9b3fSinoguchi 	}
226145d9b3fSinoguchi 	p = pt(buf, len);
227145d9b3fSinoguchi 	if (strcmp(p, (char *)test[4].digest) != 0) {
228145d9b3fSinoguchi 		printf("Error calculating interim HMAC on test 5\n");
229145d9b3fSinoguchi 		printf("got %s instead of %s\n", p, test[4].digest);
230145d9b3fSinoguchi 		err++;
231145d9b3fSinoguchi 		goto test6;
232145d9b3fSinoguchi 	}
2331c94e884Stb 	if (HMAC_Init_ex(ctx, NULL, 0, EVP_sha256(), NULL)) {
234145d9b3fSinoguchi 		printf("Should disallow changing MD without a new key (test 5)\n");
235145d9b3fSinoguchi 		err++;
236145d9b3fSinoguchi 		goto test6;
237145d9b3fSinoguchi 	}
2381c94e884Stb 	if (!HMAC_Init_ex(ctx, test[4].key, test[4].key_len, EVP_sha256(), NULL)) {
239145d9b3fSinoguchi 		printf("Failed to reinitialise HMAC (test 5)\n");
240145d9b3fSinoguchi 		err++;
241145d9b3fSinoguchi 		goto test6;
242145d9b3fSinoguchi 	}
2431c94e884Stb 	if (!HMAC_Update(ctx, test[5].data, test[5].data_len)) {
244145d9b3fSinoguchi 		printf("Error updating HMAC with data (sha256) (test 5)\n");
245145d9b3fSinoguchi 		err++;
246145d9b3fSinoguchi 		goto test6;
247145d9b3fSinoguchi 	}
2481c94e884Stb 	if (!HMAC_Final(ctx, buf, &len)) {
249145d9b3fSinoguchi 		printf("Error finalising data (sha256) (test 5)\n");
250145d9b3fSinoguchi 		err++;
251145d9b3fSinoguchi 		goto test6;
252145d9b3fSinoguchi 	}
253145d9b3fSinoguchi 	p = pt(buf, len);
254145d9b3fSinoguchi 	if (strcmp(p, (char *)test[5].digest) != 0) {
255145d9b3fSinoguchi 		printf("Error calculating 2nd interim HMAC on test 5\n");
256145d9b3fSinoguchi 		printf("got %s instead of %s\n", p, test[5].digest);
257145d9b3fSinoguchi 		err++;
258145d9b3fSinoguchi 		goto test6;
259145d9b3fSinoguchi 	}
2601c94e884Stb 	if (!HMAC_Init_ex(ctx, test[6].key, test[6].key_len, NULL, NULL)) {
261145d9b3fSinoguchi 		printf("Failed to reinitialise HMAC with key (test 5)\n");
262145d9b3fSinoguchi 		err++;
263145d9b3fSinoguchi 		goto test6;
264145d9b3fSinoguchi 	}
2651c94e884Stb 	if (!HMAC_Update(ctx, test[6].data, test[6].data_len)) {
266145d9b3fSinoguchi 		printf("Error updating HMAC with data (new key) (test 5)\n");
267145d9b3fSinoguchi 		err++;
268145d9b3fSinoguchi 		goto test6;
269145d9b3fSinoguchi 	}
2701c94e884Stb 	if (!HMAC_Final(ctx, buf, &len)) {
271145d9b3fSinoguchi 		printf("Error finalising data (new key) (test 5)\n");
272145d9b3fSinoguchi 		err++;
273145d9b3fSinoguchi 		goto test6;
274145d9b3fSinoguchi 	}
275145d9b3fSinoguchi 	p = pt(buf, len);
276145d9b3fSinoguchi 	if (strcmp(p, (char *)test[6].digest) != 0) {
277145d9b3fSinoguchi 		printf("error calculating HMAC on test 5\n");
278145d9b3fSinoguchi 		printf("got %s instead of %s\n", p, test[6].digest);
279145d9b3fSinoguchi 		err++;
280145d9b3fSinoguchi 	} else {
281145d9b3fSinoguchi 		printf("test 5 ok\n");
282145d9b3fSinoguchi 	}
283145d9b3fSinoguchi  test6:
28463f7f39aStb 	HMAC_CTX_reset(ctx);
2851c94e884Stb 	if (!HMAC_Init_ex(ctx, test[7].key, test[7].key_len, EVP_sha1(), NULL)) {
286145d9b3fSinoguchi 		printf("Failed to initialise HMAC (test 6)\n");
287145d9b3fSinoguchi 		err++;
288145d9b3fSinoguchi 		goto end;
289145d9b3fSinoguchi 	}
2901c94e884Stb 	if (!HMAC_Update(ctx, test[7].data, test[7].data_len)) {
291145d9b3fSinoguchi 		printf("Error updating HMAC with data (test 6)\n");
292145d9b3fSinoguchi 		err++;
293145d9b3fSinoguchi 		goto end;
294145d9b3fSinoguchi 	}
2951c94e884Stb 	if ((ctx2 = HMAC_CTX_new()) == NULL) {
2961c94e884Stb 		printf("HMAC_CTX_new failed (test 6)\n");
2971c94e884Stb 		exit(1);
2981c94e884Stb 	}
2991c94e884Stb 	if (!HMAC_CTX_copy(ctx2, ctx)) {
300145d9b3fSinoguchi 		printf("Failed to copy HMAC_CTX (test 6)\n");
301145d9b3fSinoguchi 		err++;
302145d9b3fSinoguchi 		goto end;
303145d9b3fSinoguchi 	}
3041c94e884Stb 	if (!HMAC_Final(ctx2, buf, &len)) {
305145d9b3fSinoguchi 		printf("Error finalising data (test 6)\n");
306145d9b3fSinoguchi 		err++;
307145d9b3fSinoguchi 		goto end;
308145d9b3fSinoguchi 	}
309145d9b3fSinoguchi 	p = pt(buf, len);
310145d9b3fSinoguchi 	if (strcmp(p, (char *)test[7].digest) != 0) {
311145d9b3fSinoguchi 		printf("Error calculating HMAC on test 6\n");
312145d9b3fSinoguchi 		printf("got %s instead of %s\n", p, test[7].digest);
313145d9b3fSinoguchi 		err++;
314145d9b3fSinoguchi 	} else {
315145d9b3fSinoguchi 		printf("test 6 ok\n");
316145d9b3fSinoguchi 	}
317145d9b3fSinoguchi end:
3181c94e884Stb 	HMAC_CTX_free(ctx);
3191c94e884Stb 	HMAC_CTX_free(ctx2);
3203c6bd008Smiod 	exit(err);
3213c6bd008Smiod 	return(0);
3223c6bd008Smiod }
3233c6bd008Smiod 
3243c6bd008Smiod #ifndef OPENSSL_NO_MD5
325145d9b3fSinoguchi static char *
pt(unsigned char * md,unsigned int len)326145d9b3fSinoguchi pt(unsigned char *md, unsigned int len)
3273c6bd008Smiod {
328745ecb7fSbluhm 	unsigned int i;
3293c6bd008Smiod 	static char buf[80];
3303c6bd008Smiod 
331145d9b3fSinoguchi 	for (i = 0; i < len; i++)
3323c6bd008Smiod 		snprintf(buf + i * 2, sizeof(buf) - i * 2, "%02x", md[i]);
3333c6bd008Smiod 	return(buf);
3343c6bd008Smiod }
3353c6bd008Smiod #endif
336