1/* $NetBSD: h_sha1hmac.c,v 1.2 2014/01/18 02:31:14 joerg Exp $ */
2
3/*-
4 * Copyright (c) 2014 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <err.h>
30#include <fcntl.h>
31#include <stdio.h>
32#include <string.h>
33
34#include <sys/ioctl.h>
35#include <sys/time.h>
36
37#include <crypto/cryptodev.h>
38
39#define SHA1_HMAC_KEYLEN	20	/* Only key-length we support */
40
41/* Test data from RFC2202 */
42const struct {
43	int num;
44        size_t key_len;
45        size_t len;
46        unsigned char key[80];
47        unsigned char data[80];
48        unsigned char mac[20];
49} tests[] = {
50        /* Test #1 */
51	{ 1, 20, 8,
52	  { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
53	    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
54	    0x0b, 0x0b, 0x0b, 0x0b },
55	  "Hi There",
56	  { 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
57	    0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e,
58	    0xf1, 0x46, 0xbe, 0x00 }
59	},
60        /* Test #2 */
61	{ 2, 4, 28,
62	  "Jefe",
63	  "what do ya want for nothing?",
64	  { 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2,
65	    0xd2, 0x74, 0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c,
66	    0x25, 0x9a, 0x7c, 0x79 }
67	},
68        /* Test #3 */
69	{ 3, 20, 50,
70	  { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
71	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
72	    0xaa, 0xaa, 0xaa, 0xaa },
73	  { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
74	    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
75	    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
76	    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
77	    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
78	    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
79	    0xdd, 0xdd },
80	  { 0x12, 0x5d, 0x73, 0x42, 0xb9, 0xac, 0x11, 0xcd,
81	    0x91, 0xa3, 0x9a, 0xf4, 0x8a, 0xa1, 0x7b, 0x4f,
82	    0x63, 0xf1, 0x75, 0xd3 }
83	},
84        /* Test #4 */
85	{ 4, 25, 50,
86	  { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
87	    0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
88	    0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
89	    0x19 },
90	  { 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
91	    0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
92	    0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
93	    0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
94	    0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
95	    0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
96	    0xcd, 0xcd },
97	  { 0x4c, 0x90, 0x07, 0xf4, 0x02, 0x62, 0x50, 0xc6,
98	    0xbc, 0x84, 0x14, 0xf9, 0xbf, 0x50, 0xc8, 0x6c,
99	    0x2d, 0x72, 0x35, 0xda }
100	},
101        /* Test #5 */
102	{ 5, 20, 20,
103	  { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
104	    0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
105	    0x0c, 0x0c, 0x0c, 0x0c },
106	  "Test With Truncation",
107	  { 0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f,
108	    0xe7, 0xf2, 0x7b, 0xe1, 0xd5, 0x8b, 0xb9, 0x32,
109	    0x4a, 0x9a, 0x5a, 0x04 }
110	},
111        /* Test #6 */
112	{ 6, 80, 54,
113	  { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
114	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
115	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
116	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
117	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
118	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
119	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
120	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
121	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
122	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
123	  "Test Using Larger Than Block-Size Key - Hash Key First",
124	  { 0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e,
125	    0x95, 0x70, 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55,
126	    0xed, 0x40, 0x21, 0x12 }
127	},
128        /* Test #7 */
129	{ 7, 80, 73,
130	  { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
131	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
132	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
133	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
134	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
135	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
136	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
137	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
138	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
139	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
140	  "Test Using Larger Than Block-Size Key and Larger Than "
141		"One Block-Size Data",
142	  { 0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78,
143	    0x6d, 0x6b, 0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08,
144	    0xbb, 0xff, 0x1a, 0x91 }
145	},
146};
147
148int
149main(void)
150{
151	size_t i;
152	int fd, res;
153	struct session_op cs;
154	struct crypt_op co;
155	unsigned char buf[20];
156
157	fd = open("/dev/crypto", O_RDWR, 0);
158	if (fd < 0)
159		err(1, "open");
160	for (i = 0; i < __arraycount(tests); i++) {
161		if (tests[i].key_len != SHA1_HMAC_KEYLEN)
162			continue;
163
164		memset(&cs, 0, sizeof(cs));
165		cs.mac = CRYPTO_SHA1_HMAC;
166		cs.mackeylen = tests[i].key_len;
167		cs.mackey = __UNCONST(&tests[i].key);
168		res = ioctl(fd, CIOCGSESSION, &cs);
169		if (res < 0)
170			err(1, "CIOCGSESSION test %d", tests[i].num);
171
172		memset(&co, 0, sizeof(co));
173		memset(buf, 0, sizeof(buf));
174		co.ses = cs.ses;
175		co.op = COP_ENCRYPT;
176		co.len = tests[i].len;
177		co.src = __UNCONST(&tests[i].data);
178		co.mac = buf;
179		res = ioctl(fd, CIOCCRYPT, &co);
180		if (res < 0)
181			err(1, "CIOCCRYPT test %d", tests[i].num);
182
183		if (memcmp(co.mac, &tests[i].mac, sizeof(tests[i].mac)))
184			errx(1, "verification failed test %d", tests[i].num);
185
186		res = ioctl(fd, CIOCFSESSION, &cs.ses);
187		if (res < 0)
188			err(1, "CIOCFSESSION test %d", tests[i].num);
189	}
190	return 0;
191}
192