1272343Sngie/* $NetBSD: h_md5hmac.c,v 1.4 2014/01/18 02:31:14 joerg Exp $ */
2272343Sngie
3272343Sngie/*-
4272343Sngie * Copyright (c) 2014 The NetBSD Foundation, Inc.
5272343Sngie * All rights reserved.
6272343Sngie *
7272343Sngie * Redistribution and use in source and binary forms, with or without
8272343Sngie * modification, are permitted provided that the following conditions
9272343Sngie * are met:
10272343Sngie * 1. Redistributions of source code must retain the above copyright
11272343Sngie *    notice, this list of conditions and the following disclaimer.
12272343Sngie * 2. Redistributions in binary form must reproduce the above copyright
13272343Sngie *    notice, this list of conditions and the following disclaimer in the
14272343Sngie *    documentation and/or other materials provided with the distribution.
15272343Sngie *
16272343Sngie * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17272343Sngie * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18272343Sngie * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19272343Sngie * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20272343Sngie * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21272343Sngie * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22272343Sngie * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23272343Sngie * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24272343Sngie * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25272343Sngie * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26272343Sngie * POSSIBILITY OF SUCH DAMAGE.
27272343Sngie */
28272343Sngie
29272343Sngie#include <err.h>
30272343Sngie#include <fcntl.h>
31272343Sngie#include <stdio.h>
32272343Sngie#include <string.h>
33272343Sngie
34272343Sngie#include <sys/ioctl.h>
35272343Sngie#include <sys/time.h>
36272343Sngie
37272343Sngie#include <crypto/cryptodev.h>
38272343Sngie
39272343Sngie#define	MD5_HMAC_KEYLEN		16	/* Fixed key length supported */
40272343Sngie
41272343Sngie/* Test data from RFC2202 */
42272343Sngieconst struct {
43272343Sngie	int num;
44272343Sngie        size_t key_len;
45272343Sngie        size_t len;
46272343Sngie	unsigned char key[80];
47272343Sngie	unsigned char data[80];
48272343Sngie        unsigned char mac[16];
49272343Sngie} tests[] = {
50272343Sngie	/* Test #1 */
51272343Sngie	{ 1, 16, 8,
52272343Sngie	  { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
53272343Sngie	    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b },
54272343Sngie	  "Hi There",
55272343Sngie	  { 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
56272343Sngie	    0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d }
57272343Sngie	},
58272343Sngie	/* Test #2 */
59272343Sngie	{ 2, 4, 28,
60272343Sngie	  "Jefe",
61272343Sngie	  "what do ya want for nothing?",
62272343Sngie	  { 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
63272343Sngie	    0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 }
64272343Sngie	},
65272343Sngie	/* Test #3 */
66272343Sngie	{ 3, 16, 50,
67272343Sngie	  { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
68272343Sngie	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
69272343Sngie	  { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
70272343Sngie	    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
71272343Sngie	    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
72272343Sngie	    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
73272343Sngie	    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
74272343Sngie	    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
75272343Sngie	    0xdd, 0xdd },
76272343Sngie	  { 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
77272343Sngie	    0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 }
78272343Sngie	},
79272343Sngie	/* Test #4 */
80272343Sngie	{ 4, 25, 50,
81272343Sngie	  { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
82272343Sngie	    0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
83272343Sngie	    0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
84272343Sngie	    0x19 },
85272343Sngie	  { 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
86272343Sngie	    0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
87272343Sngie	    0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
88272343Sngie	    0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
89272343Sngie	    0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
90272343Sngie	    0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
91272343Sngie	    0xcd, 0xcd },
92272343Sngie	  { 0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea,
93272343Sngie	    0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79 }
94272343Sngie	},
95272343Sngie	/* Test #5 */
96272343Sngie	{ 5, 16, 20,
97272343Sngie	  { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
98272343Sngie	    0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
99272343Sngie	  "Test With Truncation",
100272343Sngie	  { 0x56, 0x46, 0x1e, 0xf2, 0x34, 0x2e, 0xdc, 0x00,
101272343Sngie	    0xf9, 0xba, 0xb9, 0x95, 0x69, 0x0e, 0xfd, 0x4c }
102272343Sngie	},
103272343Sngie	/* Test #6 */
104272343Sngie	{ 6, 80, 54,
105272343Sngie	  { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
106272343Sngie	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
107272343Sngie	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
108272343Sngie	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
109272343Sngie	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
110272343Sngie	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
111272343Sngie	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
112272343Sngie	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
113272343Sngie	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
114272343Sngie	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
115272343Sngie	  "Test Using Larger Than Block-Size Key - Hash Key First",
116272343Sngie	  { 0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f,
117272343Sngie	    0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd }
118272343Sngie	},
119272343Sngie	/* Test #7 */
120272343Sngie	{ 7, 80, 73,
121272343Sngie	  { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
122272343Sngie	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
123272343Sngie	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
124272343Sngie	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
125272343Sngie	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
126272343Sngie	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
127272343Sngie	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
128272343Sngie	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
129272343Sngie	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
130272343Sngie	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
131272343Sngie	  "Test Using Larger Than Block-Size Key and Larger "
132272343Sngie		"Than One Block-Size Data",
133272343Sngie	{ 0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee,
134272343Sngie	  0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e }
135272343Sngie	},
136272343Sngie};
137272343Sngie
138272343Sngieint
139272343Sngiemain(void)
140272343Sngie{
141272343Sngie	size_t i;
142272343Sngie	int fd, res;
143272343Sngie	struct session_op cs;
144272343Sngie	struct crypt_op co;
145272343Sngie	unsigned char buf[16];
146272343Sngie
147272343Sngie	fd = open("/dev/crypto", O_RDWR, 0);
148272343Sngie	if (fd < 0)
149272343Sngie		err(1, "open");
150272343Sngie	for (i = 0; i < __arraycount(tests); i++) {
151272343Sngie		if (tests[i].key_len != MD5_HMAC_KEYLEN)
152272343Sngie			continue;
153272343Sngie
154272343Sngie		memset(&cs, 0, sizeof(cs));
155272343Sngie		cs.mac = CRYPTO_MD5_HMAC;
156272343Sngie		cs.mackeylen = tests[i].key_len;
157272343Sngie		cs.mackey = __UNCONST(&tests[i].key);
158272343Sngie		res = ioctl(fd, CIOCGSESSION, &cs);
159272343Sngie		if (res < 0)
160272343Sngie			err(1, "CIOCGSESSION test %d", tests[i].num);
161272343Sngie
162272343Sngie		memset(&co, 0, sizeof(co));
163272343Sngie		memset(buf, 0, sizeof(buf));
164272343Sngie		co.ses = cs.ses;
165272343Sngie		co.op = COP_ENCRYPT;
166272343Sngie		co.len = tests[i].len;
167272343Sngie		co.src = __UNCONST(&tests[i].data);
168272343Sngie		co.mac = buf;
169272343Sngie		res = ioctl(fd, CIOCCRYPT, &co);
170272343Sngie		if (res < 0)
171272343Sngie			err(1, "CIOCCRYPT test %d", tests[i].num);
172272343Sngie
173272343Sngie		if (memcmp(co.mac, tests[i].mac, sizeof(tests[i].mac)))
174272343Sngie			errx(1, "verification failed test %d", tests[i].num);
175272343Sngie
176272343Sngie		res = ioctl(fd, CIOCFSESSION, &cs.ses);
177272343Sngie		if (res < 0)
178272343Sngie			err(1, "CIOCFSESSION test %d", tests[i].num);
179272343Sngie	}
180272343Sngie	return 0;
181272343Sngie}
182