1 /* $OpenBSD: markus $ */
4 * Copyright (c) 2005 Markus Friedl <markus@openbsd.org>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <sys/types.h>
20 #include <sys/param.h>
21 #include <sys/ioctl.h>
22 #include <sys/sysctl.h>
23 #include <crypto/cryptodev.h>
35 enum { TST_KEY, TST_IV, TST_PLAIN, TST_CIPHER, TST_NUM };
37 /* Test vectors from RFC 3686 */
43 "AE 68 52 F8 12 10 67 CC 4B F7 A5 76 55 77 F3 9E "
45 "00 00 00 00 00 00 00 00",
46 "53 69 6E 67 6C 65 20 62 6C 6F 63 6B 20 6D 73 67",
47 "E4 09 5D 4F B7 A7 B3 79 2D 61 75 A3 26 13 11 B8"
50 "7E 24 06 78 17 FA E0 D7 43 D6 CE 1F 32 53 91 63 "
52 "C0 54 3B 59 DA 48 D9 0B",
53 "00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F "
54 "10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F",
55 "51 04 A1 06 16 8A 72 D9 79 0D 41 EE 8E DA D3 88 "
56 "EB 2E 1E FC 46 DA 57 C8 FC E6 30 DF 91 41 BE 28"
59 "76 91 BE 03 5E 50 20 A8 AC 6E 61 85 29 F9 A0 DC "
61 "27 77 7F 3F 4A 17 86 F0",
62 "00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F "
63 "10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F"
65 "C1 CF 48 A8 9F 2F FD D9 CF 46 52 E9 EF DB 72 D7 "
66 "45 40 A4 2B DE 6D 78 36 D5 9A 5C EA AE F3 10 53"
71 "16 AF 5B 14 5F C9 F5 79 C1 75 F9 3E 3B FB 0E ED "
72 "86 3D 06 CC FD B7 85 15 "
74 "36 73 3C 14 7D 6D 93 CB",
75 "53 69 6E 67 6C 65 20 62 6C 6F 63 6B 20 6D 73 67",
76 "4B 55 38 4F E2 59 C9 C8 4E 79 35 A0 03 CB E9 28",
79 "7C 5C B2 40 1B 3D C3 3C 19 E7 34 08 19 E0 F6 9C "
80 "67 8C 3D B8 E6 F6 A9 1A "
82 "02 0C 6E AD C2 CB 50 0D",
83 "00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F "
84 "10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F",
85 "45 32 43 FC 60 9B 23 32 7E DF AA FA 71 31 CD 9F "
86 "84 90 70 1C 5A D4 A7 9C FC 1F E0 FF 42 F4 FB 00",
89 "02 BF 39 1E E8 EC B1 59 B9 59 61 7B 09 65 27 9B "
90 "F5 9B 60 A7 86 D3 E0 FE "
92 "5C BD 60 27 8D CC 09 12",
93 "00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F "
94 "10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F"
96 "96 89 3F C5 5E 5C 72 2F 54 0B 7D D1 DD F7 E7 58 "
97 "D2 88 BC 95 C6 91 65 88 45 36 C8 11 66 2F 21 88"
102 "77 6B EF F2 85 1D B0 6F 4C 8A 05 42 C8 69 6F 6C "
103 "6A 81 AF 1E EC 96 B4 D3 7F C1 D6 89 E6 C1 C1 04 "
105 "DB 56 72 C9 7A A8 F0 B2",
106 "53 69 6E 67 6C 65 20 62 6C 6F 63 6B 20 6D 73 67",
107 "14 5A D0 1D BF 82 4E C7 56 08 63 DC 71 E3 E0 C0"
110 "F6 D6 6D 6B D5 2D 59 BB 07 96 36 58 79 EF F8 86 "
111 "C6 6D D5 1A 5B 6A 99 74 4B 50 59 0C 87 A2 38 84 "
113 "C1 58 5E F1 5A 43 D8 75",
114 "00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F "
115 "10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F",
116 "F0 5E 23 1B 38 94 61 2C 49 EE 00 0B 80 4E B2 A9 "
117 "B8 30 6B 50 8F 83 9D 6A 55 30 83 1D 93 44 AF 1C",
120 "FF 7A 61 7C E6 91 48 E4 F1 72 6E 2F 43 58 1D E2 "
121 "AA 62 D9 F8 05 53 2E DF F1 EE D6 87 FB 54 15 3D "
123 "51 A5 1D 70 A1 C1 11 48",
124 "00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F "
125 "10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F"
127 "EB 6C 52 82 1D 0B BB F7 CE 75 94 46 2A CA 4F AA "
128 "B4 07 DF 86 65 69 FD 07 F4 8C C0 B5 83 D6 07 1F"
134 syscrypt(const unsigned char *key, size_t klen, const unsigned char *iv,
135 const unsigned char *in, unsigned char *out, size_t len, int encrypt)
137 struct session_op session;
138 struct crypt_op cryp;
139 int cryptodev_fd = -1, fd = -1;
141 if ((cryptodev_fd = open("/dev/crypto", O_RDWR, 0)) < 0) {
145 if (ioctl(cryptodev_fd, CRIOGET, &fd) == -1) {
146 warn("CRIOGET failed");
149 memset(&session, 0, sizeof(session));
150 session.cipher = CRYPTO_AES_CTR;
151 session.key = (caddr_t) key;
152 session.keylen = klen;
153 if (ioctl(fd, CIOCGSESSION, &session) == -1) {
154 warn("CIOCGSESSION");
157 memset(&cryp, 0, sizeof(cryp));
158 cryp.ses = session.ses;
159 cryp.op = encrypt ? COP_ENCRYPT : COP_DECRYPT;
162 cryp.src = (caddr_t) in;
163 cryp.dst = (caddr_t) out;
164 cryp.iv = (caddr_t) iv;
166 if (ioctl(fd, CIOCCRYPT, &cryp) == -1) {
170 if (ioctl(fd, CIOCFSESSION, &session.ses) == -1) {
171 warn("CIOCFSESSION");
181 if (cryptodev_fd != -1)
194 if (sysctlbyname("kern.cryptodevallowsoft", &old, &olen, NULL, 0) < 0)
195 err(1, "sysctl failed");
201 setallowsoft(int new)
206 olen = nlen = sizeof(new);
208 if (sysctlbyname("kern.cryptodevallowsoft", &old, &olen, &new, nlen) < 0)
209 err(1, "sysctl failed");
213 match(unsigned char *a, unsigned char *b, size_t len)
217 if (memcmp(a, b, len) == 0)
220 warnx("ciphertext mismatch");
222 for (i = 0; i < len; i++)
223 printf("%2.2x", a[i]);
225 for (i = 0; i < len; i++)
226 printf("%2.2x", b[i]);
235 int i, fail = 1, len, j, length[TST_NUM];
238 u_char *p, *data[TST_NUM];
240 for (i = 0; i < TST_NUM; i++)
242 for (i = 0; i < TST_NUM; i++) {
243 from = tests[num].data[i];
245 printf("%s\n", from);
247 if ((p = malloc(len)) == NULL) {
252 for (j = 0; j < len; j++) {
253 val = strtoul(&from[j*3], &ep, 16);
255 if (*ep == '\0' || errno)
261 len = length[TST_PLAIN];
262 if ((p = malloc(len)) == NULL) {
266 if (syscrypt(data[TST_KEY], length[TST_KEY],
267 data[TST_IV], data[TST_PLAIN], p,
268 length[TST_PLAIN], 0) < 0) {
269 warnx("crypt with /dev/crypto failed");
272 fail = !match(data[TST_CIPHER], p, len);
273 printf("%s test vector %d\n", fail ? "FAILED" : "OK", num);
275 for (i = 0; i < TST_NUM; i++)
281 main(int argc, char **argv)
283 int allowed = 0, fail = 0, i;
285 if (geteuid() == 0) {
286 allowed = getallowsoft();
290 for (i = 0; i < (sizeof(tests) / sizeof(tests[0])); i++)
292 if (geteuid() == 0 && allowed == 0)
294 exit((fail > 0) ? 1 : 0);