xref: /dflybsd-src/lib/libtcplay/crypto-dev.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
1*86d7f5d3SJohn Marino /*
2*86d7f5d3SJohn Marino  * Copyright (c) 2011 Alex Hornung <alex@alexhornung.com>.
3*86d7f5d3SJohn Marino  * All rights reserved.
4*86d7f5d3SJohn Marino  *
5*86d7f5d3SJohn Marino  * Redistribution and use in source and binary forms, with or without
6*86d7f5d3SJohn Marino  * modification, are permitted provided that the following conditions
7*86d7f5d3SJohn Marino  * are met:
8*86d7f5d3SJohn Marino  *
9*86d7f5d3SJohn Marino  * 1. Redistributions of source code must retain the above copyright
10*86d7f5d3SJohn Marino  *    notice, this list of conditions and the following disclaimer.
11*86d7f5d3SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
12*86d7f5d3SJohn Marino  *    notice, this list of conditions and the following disclaimer in
13*86d7f5d3SJohn Marino  *    the documentation and/or other materials provided with the
14*86d7f5d3SJohn Marino  *    distribution.
15*86d7f5d3SJohn Marino  *
16*86d7f5d3SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17*86d7f5d3SJohn Marino  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18*86d7f5d3SJohn Marino  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19*86d7f5d3SJohn Marino  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
20*86d7f5d3SJohn Marino  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21*86d7f5d3SJohn Marino  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
22*86d7f5d3SJohn Marino  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23*86d7f5d3SJohn Marino  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24*86d7f5d3SJohn Marino  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25*86d7f5d3SJohn Marino  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26*86d7f5d3SJohn Marino  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27*86d7f5d3SJohn Marino  * SUCH DAMAGE.
28*86d7f5d3SJohn Marino  */
29*86d7f5d3SJohn Marino #include <sys/types.h>
30*86d7f5d3SJohn Marino #include <sys/param.h>
31*86d7f5d3SJohn Marino #include <sys/ioctl.h>
32*86d7f5d3SJohn Marino #include <sys/sysctl.h>
33*86d7f5d3SJohn Marino #include <crypto/cryptodev.h>
34*86d7f5d3SJohn Marino 
35*86d7f5d3SJohn Marino #include <fcntl.h>
36*86d7f5d3SJohn Marino #include <unistd.h>
37*86d7f5d3SJohn Marino #include <errno.h>
38*86d7f5d3SJohn Marino #include <string.h>
39*86d7f5d3SJohn Marino #include <stdio.h>
40*86d7f5d3SJohn Marino 
41*86d7f5d3SJohn Marino #include "tcplay.h"
42*86d7f5d3SJohn Marino 
43*86d7f5d3SJohn Marino static
44*86d7f5d3SJohn Marino int
getallowsoft(void)45*86d7f5d3SJohn Marino getallowsoft(void)
46*86d7f5d3SJohn Marino {
47*86d7f5d3SJohn Marino 	int old;
48*86d7f5d3SJohn Marino 	size_t olen;
49*86d7f5d3SJohn Marino 
50*86d7f5d3SJohn Marino 	olen = sizeof(old);
51*86d7f5d3SJohn Marino 
52*86d7f5d3SJohn Marino 	if (sysctlbyname("kern.cryptodevallowsoft", &old, &olen, NULL, 0) < 0) {
53*86d7f5d3SJohn Marino 		perror("accessing sysctl kern.cryptodevallowsoft failed");
54*86d7f5d3SJohn Marino 	}
55*86d7f5d3SJohn Marino 
56*86d7f5d3SJohn Marino 	return old;
57*86d7f5d3SJohn Marino }
58*86d7f5d3SJohn Marino 
59*86d7f5d3SJohn Marino static
60*86d7f5d3SJohn Marino void
setallowsoft(int new)61*86d7f5d3SJohn Marino setallowsoft(int new)
62*86d7f5d3SJohn Marino {
63*86d7f5d3SJohn Marino 	int old;
64*86d7f5d3SJohn Marino 	size_t olen, nlen;
65*86d7f5d3SJohn Marino 
66*86d7f5d3SJohn Marino 	olen = nlen = sizeof(new);
67*86d7f5d3SJohn Marino 
68*86d7f5d3SJohn Marino 	if (sysctlbyname("kern.cryptodevallowsoft", &old, &olen, &new, nlen) < 0) {
69*86d7f5d3SJohn Marino 		perror("accessing sysctl kern.cryptodevallowsoft failed");
70*86d7f5d3SJohn Marino 	}
71*86d7f5d3SJohn Marino }
72*86d7f5d3SJohn Marino 
73*86d7f5d3SJohn Marino static
74*86d7f5d3SJohn Marino int
get_cryptodev_cipher_id(struct tc_crypto_algo * cipher)75*86d7f5d3SJohn Marino get_cryptodev_cipher_id(struct tc_crypto_algo *cipher)
76*86d7f5d3SJohn Marino {
77*86d7f5d3SJohn Marino 	if	(strcmp(cipher->name, "AES-128-XTS") == 0)
78*86d7f5d3SJohn Marino 		return CRYPTO_AES_XTS;
79*86d7f5d3SJohn Marino 	else if (strcmp(cipher->name, "AES-256-XTS") == 0)
80*86d7f5d3SJohn Marino 		return CRYPTO_AES_XTS;
81*86d7f5d3SJohn Marino 	else if (strcmp(cipher->name, "TWOFISH-128-XTS") == 0)
82*86d7f5d3SJohn Marino 		return CRYPTO_TWOFISH_XTS;
83*86d7f5d3SJohn Marino 	else if (strcmp(cipher->name, "TWOFISH-256-XTS") == 0)
84*86d7f5d3SJohn Marino 		return CRYPTO_TWOFISH_XTS;
85*86d7f5d3SJohn Marino 	else if (strcmp(cipher->name, "SERPENT-128-XTS") == 0)
86*86d7f5d3SJohn Marino 		return CRYPTO_SERPENT_XTS;
87*86d7f5d3SJohn Marino 	else if (strcmp(cipher->name, "SERPENT-256-XTS") == 0)
88*86d7f5d3SJohn Marino 		return CRYPTO_SERPENT_XTS;
89*86d7f5d3SJohn Marino 	else
90*86d7f5d3SJohn Marino 		return -1;
91*86d7f5d3SJohn Marino }
92*86d7f5d3SJohn Marino 
93*86d7f5d3SJohn Marino int
syscrypt(struct tc_crypto_algo * cipher,unsigned char * key,size_t klen,unsigned char * iv,unsigned char * in,unsigned char * out,size_t len,int do_encrypt)94*86d7f5d3SJohn Marino syscrypt(struct tc_crypto_algo *cipher, unsigned char *key, size_t klen, unsigned char *iv,
95*86d7f5d3SJohn Marino     unsigned char *in, unsigned char *out, size_t len, int do_encrypt)
96*86d7f5d3SJohn Marino {
97*86d7f5d3SJohn Marino 	struct session_op session;
98*86d7f5d3SJohn Marino 	struct crypt_op cryp;
99*86d7f5d3SJohn Marino 	int cipher_id;
100*86d7f5d3SJohn Marino 	int cryptodev_fd = -1, fd = -1;
101*86d7f5d3SJohn Marino 
102*86d7f5d3SJohn Marino 	cipher_id = get_cryptodev_cipher_id(cipher);
103*86d7f5d3SJohn Marino 	if (cipher_id < 0) {
104*86d7f5d3SJohn Marino 		tc_log(1, "Cipher %s not found\n",
105*86d7f5d3SJohn Marino 		    cipher->name);
106*86d7f5d3SJohn Marino 		return ENOENT;
107*86d7f5d3SJohn Marino 	}
108*86d7f5d3SJohn Marino 
109*86d7f5d3SJohn Marino 	if ((cryptodev_fd = open("/dev/crypto", O_RDWR, 0)) < 0) {
110*86d7f5d3SJohn Marino 		perror("Could not open /dev/crypto");
111*86d7f5d3SJohn Marino 		goto err;
112*86d7f5d3SJohn Marino 	}
113*86d7f5d3SJohn Marino 	if (ioctl(cryptodev_fd, CRIOGET, &fd) == -1) {
114*86d7f5d3SJohn Marino 		perror("CRIOGET failed");
115*86d7f5d3SJohn Marino 		goto err;
116*86d7f5d3SJohn Marino 	}
117*86d7f5d3SJohn Marino 	memset(&session, 0, sizeof(session));
118*86d7f5d3SJohn Marino 	session.cipher = cipher_id;
119*86d7f5d3SJohn Marino 	session.key = (caddr_t) key;
120*86d7f5d3SJohn Marino 	session.keylen = klen;
121*86d7f5d3SJohn Marino 	if (ioctl(fd, CIOCGSESSION, &session) == -1) {
122*86d7f5d3SJohn Marino 		perror("CIOCGSESSION failed");
123*86d7f5d3SJohn Marino 		goto err;
124*86d7f5d3SJohn Marino 	}
125*86d7f5d3SJohn Marino 	memset(&cryp, 0, sizeof(cryp));
126*86d7f5d3SJohn Marino 	cryp.ses = session.ses;
127*86d7f5d3SJohn Marino 	cryp.op = do_encrypt ? COP_ENCRYPT : COP_DECRYPT;
128*86d7f5d3SJohn Marino 	cryp.flags = 0;
129*86d7f5d3SJohn Marino 	cryp.len = len;
130*86d7f5d3SJohn Marino 	cryp.src = (caddr_t) in;
131*86d7f5d3SJohn Marino 	cryp.dst = (caddr_t) out;
132*86d7f5d3SJohn Marino 	cryp.iv = (caddr_t) iv;
133*86d7f5d3SJohn Marino 	cryp.mac = 0;
134*86d7f5d3SJohn Marino 	if (ioctl(fd, CIOCCRYPT, &cryp) == -1) {
135*86d7f5d3SJohn Marino 		perror("CIOCCRYPT failed");
136*86d7f5d3SJohn Marino 		goto err;
137*86d7f5d3SJohn Marino 	}
138*86d7f5d3SJohn Marino 	if (ioctl(fd, CIOCFSESSION, &session.ses) == -1) {
139*86d7f5d3SJohn Marino 		perror("CIOCFSESSION failed");
140*86d7f5d3SJohn Marino 		goto err;
141*86d7f5d3SJohn Marino 	}
142*86d7f5d3SJohn Marino 	close(fd);
143*86d7f5d3SJohn Marino 	close(cryptodev_fd);
144*86d7f5d3SJohn Marino 	return (0);
145*86d7f5d3SJohn Marino 
146*86d7f5d3SJohn Marino err:
147*86d7f5d3SJohn Marino 	if (fd != -1)
148*86d7f5d3SJohn Marino 		close(fd);
149*86d7f5d3SJohn Marino 	if (cryptodev_fd != -1)
150*86d7f5d3SJohn Marino 		close(cryptodev_fd);
151*86d7f5d3SJohn Marino 	return (-1);
152*86d7f5d3SJohn Marino }
153*86d7f5d3SJohn Marino 
154*86d7f5d3SJohn Marino int
tc_crypto_init(void)155*86d7f5d3SJohn Marino tc_crypto_init(void)
156*86d7f5d3SJohn Marino {
157*86d7f5d3SJohn Marino 	int allowed;
158*86d7f5d3SJohn Marino 
159*86d7f5d3SJohn Marino 	allowed = getallowsoft();
160*86d7f5d3SJohn Marino 	if (allowed == 0)
161*86d7f5d3SJohn Marino 		setallowsoft(1);
162*86d7f5d3SJohn Marino 
163*86d7f5d3SJohn Marino 	return 0;
164*86d7f5d3SJohn Marino }
165*86d7f5d3SJohn Marino 
166