1 /* $OpenBSD: markus $ */ 2 3 /* 4 * Copyright (c) 2005 Markus Friedl <markus@openbsd.org> 5 * 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. 9 * 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. 17 */ 18 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> 24 #include <err.h> 25 #include <fcntl.h> 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <string.h> 29 #include <unistd.h> 30 #include <limits.h> 31 #include <errno.h> 32 33 int debug = 0; 34 35 enum { TST_KEY, TST_IV, TST_PLAIN, TST_CIPHER, TST_NUM }; 36 37 /* Test vectors from RFC 3686 */ 38 struct { 39 char *data[TST_NUM]; 40 } tests[] = { 41 /* 128 bit key */ 42 { 43 "AE 68 52 F8 12 10 67 CC 4B F7 A5 76 55 77 F3 9E " 44 "00 00 00 30", 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" 48 }, 49 { 50 "7E 24 06 78 17 FA E0 D7 43 D6 CE 1F 32 53 91 63 " 51 "00 6C B6 DB", 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" 57 }, 58 { 59 "76 91 BE 03 5E 50 20 A8 AC 6E 61 85 29 F9 A0 DC " 60 "00 E0 01 7B", 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" 64 /*"20 21 22 23"*/, 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" 67 /*"25 B2 07 2F"*/ 68 }, 69 /* 192 bit key */ 70 { 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 " 73 "00 00 00 48", 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", 77 }, 78 { 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 " 81 "00 96 B0 3B", 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", 87 }, 88 { 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 " 91 "00 07 BD FD", 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" 95 /*"20 21 22 23"*/, 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" 98 /*"AB EE 09 35"*/, 99 }, 100 /* 256 bit key */ 101 { 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 " 104 "00 00 00 60", 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" 108 }, 109 { 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 " 112 "00 FA AC 24", 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", 118 }, 119 { 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 " 122 "00 1C C5 B7", 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" 126 /*"20 21 22 23"*/, 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" 129 /*"1E C0 E6 B8"*/, 130 }, 131 }; 132 133 static int 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) 136 { 137 struct session_op session; 138 struct crypt_op cryp; 139 int cryptodev_fd = -1, fd = -1; 140 141 if ((cryptodev_fd = open("/dev/crypto", O_RDWR, 0)) < 0) { 142 warn("/dev/crypto"); 143 goto err; 144 } 145 if (ioctl(cryptodev_fd, CRIOGET, &fd) == -1) { 146 warn("CRIOGET failed"); 147 goto err; 148 } 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"); 155 goto err; 156 } 157 memset(&cryp, 0, sizeof(cryp)); 158 cryp.ses = session.ses; 159 cryp.op = encrypt ? COP_ENCRYPT : COP_DECRYPT; 160 cryp.flags = 0; 161 cryp.len = len; 162 cryp.src = (caddr_t) in; 163 cryp.dst = (caddr_t) out; 164 cryp.iv = (caddr_t) iv; 165 cryp.mac = 0; 166 if (ioctl(fd, CIOCCRYPT, &cryp) == -1) { 167 warn("CIOCCRYPT"); 168 goto err; 169 } 170 if (ioctl(fd, CIOCFSESSION, &session.ses) == -1) { 171 warn("CIOCFSESSION"); 172 goto err; 173 } 174 close(fd); 175 close(cryptodev_fd); 176 return (0); 177 178 err: 179 if (fd != -1) 180 close(fd); 181 if (cryptodev_fd != -1) 182 close(cryptodev_fd); 183 return (-1); 184 } 185 186 static int 187 getallowsoft(void) 188 { 189 int mib[2], old; 190 size_t olen; 191 192 olen = sizeof(old); 193 194 if (sysctlbyname("kern.cryptodevallowsoft", &old, &olen, NULL, 0) < 0) 195 err(1, "sysctl failed"); 196 197 return old; 198 } 199 200 static void 201 setallowsoft(int new) 202 { 203 int mib[2], old; 204 size_t olen, nlen; 205 206 olen = nlen = sizeof(new); 207 208 if (sysctlbyname("kern.cryptodevallowsoft", &old, &olen, &new, nlen) < 0) 209 err(1, "sysctl failed"); 210 } 211 212 static int 213 match(unsigned char *a, unsigned char *b, size_t len) 214 { 215 int i; 216 217 if (memcmp(a, b, len) == 0) 218 return (1); 219 220 warnx("ciphertext mismatch"); 221 222 for (i = 0; i < len; i++) 223 printf("%2.2x", a[i]); 224 printf("\n"); 225 for (i = 0; i < len; i++) 226 printf("%2.2x", b[i]); 227 printf("\n"); 228 229 return (0); 230 } 231 232 static int 233 run(int num) 234 { 235 int i, fail = 1, len, j, length[TST_NUM]; 236 u_long val; 237 char *ep, *from; 238 u_char *p, *data[TST_NUM]; 239 240 for (i = 0; i < TST_NUM; i++) 241 data[i] = NULL; 242 for (i = 0; i < TST_NUM; i++) { 243 from = tests[num].data[i]; 244 if (debug) 245 printf("%s\n", from); 246 len = strlen(from); 247 if ((p = malloc(len)) == NULL) { 248 warn("malloc"); 249 goto done; 250 } 251 errno = 0; 252 for (j = 0; j < len; j++) { 253 val = strtoul(&from[j*3], &ep, 16); 254 p[j] = (u_char)val; 255 if (*ep == '\0' || errno) 256 break; 257 } 258 length[i] = j+1; 259 data[i] = p; 260 } 261 len = length[TST_PLAIN]; 262 if ((p = malloc(len)) == NULL) { 263 warn("malloc"); 264 return (1); 265 } 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"); 270 goto done; 271 } 272 fail = !match(data[TST_CIPHER], p, len); 273 printf("%s test vector %d\n", fail ? "FAILED" : "OK", num); 274 done: 275 for (i = 0; i < TST_NUM; i++) 276 free(data[i]); 277 return (fail); 278 } 279 280 int 281 main(int argc, char **argv) 282 { 283 int allowed = 0, fail = 0, i; 284 285 if (geteuid() == 0) { 286 allowed = getallowsoft(); 287 if (allowed == 0) 288 setallowsoft(1); 289 } 290 for (i = 0; i < NELEM(tests); i++) 291 fail += run(i); 292 if (geteuid() == 0 && allowed == 0) 293 setallowsoft(0); 294 exit((fail > 0) ? 1 : 0); 295 } 296