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