1 /* $NetBSD: h_md5hmac.c,v 1.4 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	MD5_HMAC_KEYLEN		16	/* Fixed key length supported */
40 
41 /* Test data from RFC2202 */
42 const 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[16];
49 } tests[] = {
50 	/* Test #1 */
51 	{ 1, 16, 8,
52 	  { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
53 	    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b },
54 	  "Hi There",
55 	  { 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
56 	    0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d }
57 	},
58 	/* Test #2 */
59 	{ 2, 4, 28,
60 	  "Jefe",
61 	  "what do ya want for nothing?",
62 	  { 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
63 	    0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 }
64 	},
65 	/* Test #3 */
66 	{ 3, 16, 50,
67 	  { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
68 	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
69 	  { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
70 	    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
71 	    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
72 	    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
73 	    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
74 	    0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
75 	    0xdd, 0xdd },
76 	  { 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
77 	    0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 }
78 	},
79 	/* Test #4 */
80 	{ 4, 25, 50,
81 	  { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
82 	    0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
83 	    0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
84 	    0x19 },
85 	  { 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
86 	    0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
87 	    0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
88 	    0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
89 	    0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
90 	    0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
91 	    0xcd, 0xcd },
92 	  { 0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea,
93 	    0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79 }
94 	},
95 	/* Test #5 */
96 	{ 5, 16, 20,
97 	  { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
98 	    0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
99 	  "Test With Truncation",
100 	  { 0x56, 0x46, 0x1e, 0xf2, 0x34, 0x2e, 0xdc, 0x00,
101 	    0xf9, 0xba, 0xb9, 0x95, 0x69, 0x0e, 0xfd, 0x4c }
102 	},
103 	/* Test #6 */
104 	{ 6, 80, 54,
105 	  { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
106 	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
107 	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
108 	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
109 	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
110 	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
111 	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
112 	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
113 	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
114 	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
115 	  "Test Using Larger Than Block-Size Key - Hash Key First",
116 	  { 0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f,
117 	    0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd }
118 	},
119 	/* Test #7 */
120 	{ 7, 80, 73,
121 	  { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
122 	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
123 	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
124 	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
125 	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
126 	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
127 	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
128 	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
129 	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
130 	    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
131 	  "Test Using Larger Than Block-Size Key and Larger "
132 		"Than One Block-Size Data",
133 	{ 0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee,
134 	  0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e }
135 	},
136 };
137 
138 int
139 main(void)
140 {
141 	size_t i;
142 	int fd, res;
143 	struct session_op cs;
144 	struct crypt_op co;
145 	unsigned char buf[16];
146 
147 	fd = open("/dev/crypto", O_RDWR, 0);
148 	if (fd < 0)
149 		err(1, "open");
150 	for (i = 0; i < __arraycount(tests); i++) {
151 		if (tests[i].key_len != MD5_HMAC_KEYLEN)
152 			continue;
153 
154 		memset(&cs, 0, sizeof(cs));
155 		cs.mac = CRYPTO_MD5_HMAC;
156 		cs.mackeylen = tests[i].key_len;
157 		cs.mackey = __UNCONST(&tests[i].key);
158 		res = ioctl(fd, CIOCGSESSION, &cs);
159 		if (res < 0)
160 			err(1, "CIOCGSESSION test %d", tests[i].num);
161 
162 		memset(&co, 0, sizeof(co));
163 		memset(buf, 0, sizeof(buf));
164 		co.ses = cs.ses;
165 		co.op = COP_ENCRYPT;
166 		co.len = tests[i].len;
167 		co.src = __UNCONST(&tests[i].data);
168 		co.mac = buf;
169 		res = ioctl(fd, CIOCCRYPT, &co);
170 		if (res < 0)
171 			err(1, "CIOCCRYPT test %d", tests[i].num);
172 
173 		if (memcmp(co.mac, tests[i].mac, sizeof(tests[i].mac)))
174 			errx(1, "verification failed test %d", tests[i].num);
175 
176 		res = ioctl(fd, CIOCFSESSION, &cs.ses);
177 		if (res < 0)
178 			err(1, "CIOCFSESSION test %d", tests[i].num);
179 	}
180 	return 0;
181 }
182