1 /* $FreeBSD: src/sys/opencrypto/cryptodev.c,v 1.41 2009/09/04 09:48:18 pjd Exp $ */
2 /* $OpenBSD: cryptodev.c,v 1.52 2002/06/19 07:22:46 deraadt Exp $ */
5 * Copyright (c) 2001 Theo de Raadt
6 * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 * Effort sponsored in part by the Defense Advanced Research Projects
32 * Agency (DARPA) and Air Force Research Laboratory, Air Force
33 * Materiel Command, USAF, under agreement number F30602-01-2-0537.
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/malloc.h>
39 #include <sys/device.h>
42 #include <sys/sysctl.h>
44 #include <sys/filedesc.h>
45 #include <sys/errno.h>
47 #include <sys/random.h>
49 #include <sys/module.h>
50 #include <sys/kernel.h>
51 #include <sys/fcntl.h>
53 #include <sys/file2.h>
54 #include <sys/thread2.h>
56 #include <opencrypto/cryptodev.h>
57 #include <opencrypto/xform.h>
60 TAILQ_ENTRY(csession
) next
;
66 struct enc_xform
*txform
;
68 struct auth_hash
*thash
;
72 u_char tmp_iv
[EALG_MAX_BLOCK_LEN
];
83 TAILQ_HEAD(csessionlist
, csession
) csessions
;
87 static int cryptof_rw(struct file
*fp
, struct uio
*uio
,
88 struct ucred
*cred
, int flags
);
89 static int cryptof_ioctl(struct file
*, u_long
, caddr_t
,
90 struct ucred
*, struct sysmsg
*);
91 static int cryptof_poll(struct file
*, int, struct ucred
*);
92 static int cryptof_kqfilter(struct file
*, struct knote
*);
93 static int cryptof_stat(struct file
*, struct stat
*, struct ucred
*);
94 static int cryptof_close(struct file
*);
96 static struct fileops cryptofops
= {
97 .fo_read
= cryptof_rw
,
98 .fo_write
= cryptof_rw
,
99 .fo_ioctl
= cryptof_ioctl
,
100 .fo_poll
= cryptof_poll
,
101 .fo_kqfilter
= cryptof_kqfilter
,
102 .fo_stat
= cryptof_stat
,
103 .fo_close
= cryptof_close
,
104 .fo_shutdown
= nofo_shutdown
107 static struct csession
*csefind(struct fcrypt
*, u_int
);
108 static int csedelete(struct fcrypt
*, struct csession
*);
109 static struct csession
*cseadd(struct fcrypt
*, struct csession
*);
110 static struct csession
*csecreate(struct fcrypt
*, u_int64_t
, caddr_t
,
111 u_int64_t
, caddr_t
, u_int64_t
, u_int32_t
, u_int32_t
, struct enc_xform
*,
113 static int csefree(struct csession
*);
115 static int cryptodev_op(struct csession
*, struct crypt_op
*, struct ucred
*);
116 static int cryptodev_key(struct crypt_kop
*);
117 static int cryptodev_find(struct crypt_find_op
*);
123 struct ucred
*active_cred
,
130 * Check a crypto identifier to see if it requested
131 * a software device/driver. This can be done either
132 * by device name/class or through search constraints.
135 checkforsoftware(int crid
)
137 if (crid
& CRYPTOCAP_F_SOFTWARE
)
138 return EINVAL
; /* XXX */
139 if ((crid
& CRYPTOCAP_F_HARDWARE
) == 0 &&
140 (crypto_getcaps(crid
) & CRYPTOCAP_F_HARDWARE
) == 0)
141 return EINVAL
; /* XXX */
147 cryptof_ioctl(struct file
*fp
, u_long cmd
, caddr_t data
,
148 struct ucred
*cred
, struct sysmsg
*msg
)
150 #define SES2(p) ((struct session2_op *)p)
151 struct cryptoini cria
, crie
;
152 struct fcrypt
*fcr
= fp
->f_data
;
153 struct csession
*cse
;
154 struct session_op
*sop
;
155 struct crypt_op
*cop
;
156 struct enc_xform
*txform
= NULL
;
157 struct auth_hash
*thash
= NULL
;
158 struct crypt_kop
*kop
;
166 sop
= (struct session_op
*)data
;
167 switch (sop
->cipher
) {
171 txform
= &enc_xform_des
;
173 case CRYPTO_3DES_CBC
:
174 txform
= &enc_xform_3des
;
177 txform
= &enc_xform_blf
;
179 case CRYPTO_CAST_CBC
:
180 txform
= &enc_xform_cast5
;
182 case CRYPTO_SKIPJACK_CBC
:
183 txform
= &enc_xform_skipjack
;
186 txform
= &enc_xform_rijndael128
;
188 case CRYPTO_NULL_CBC
:
189 txform
= &enc_xform_null
;
192 txform
= &enc_xform_arc4
;
194 case CRYPTO_CAMELLIA_CBC
:
195 txform
= &enc_xform_camellia
;
204 case CRYPTO_MD5_HMAC
:
205 thash
= &auth_hash_hmac_md5
;
207 case CRYPTO_SHA1_HMAC
:
208 thash
= &auth_hash_hmac_sha1
;
210 case CRYPTO_SHA2_256_HMAC
:
211 thash
= &auth_hash_hmac_sha2_256
;
213 case CRYPTO_SHA2_384_HMAC
:
214 thash
= &auth_hash_hmac_sha2_384
;
216 case CRYPTO_SHA2_512_HMAC
:
217 thash
= &auth_hash_hmac_sha2_512
;
219 case CRYPTO_RIPEMD160_HMAC
:
220 thash
= &auth_hash_hmac_ripemd_160
;
224 thash
= &auth_hash_md5
;
227 thash
= &auth_hash_sha1
;
230 case CRYPTO_NULL_HMAC
:
231 thash
= &auth_hash_null
;
237 bzero(&crie
, sizeof(crie
));
238 bzero(&cria
, sizeof(cria
));
241 crie
.cri_alg
= txform
->type
;
242 crie
.cri_klen
= sop
->keylen
* 8;
243 if (sop
->keylen
> txform
->maxkey
||
244 sop
->keylen
< txform
->minkey
) {
249 crie
.cri_key
= kmalloc(crie
.cri_klen
/ 8,
251 if ((error
= copyin(sop
->key
, crie
.cri_key
,
255 crie
.cri_next
= &cria
;
259 cria
.cri_alg
= thash
->type
;
260 cria
.cri_klen
= sop
->mackeylen
* 8;
261 if (sop
->mackeylen
!= thash
->keysize
) {
267 cria
.cri_key
= kmalloc(cria
.cri_klen
/ 8,
269 if ((error
= copyin(sop
->mackey
, cria
.cri_key
,
275 /* NB: CIOGSESSION2 has the crid */
276 if (cmd
== CIOCGSESSION2
) {
277 crid
= SES2(sop
)->crid
;
278 error
= checkforsoftware(crid
);
282 crid
= CRYPTOCAP_F_HARDWARE
;
283 error
= crypto_newsession(&sid
, (txform
? &crie
: &cria
), crid
);
287 cse
= csecreate(fcr
, sid
, crie
.cri_key
, crie
.cri_klen
,
288 cria
.cri_key
, cria
.cri_klen
, sop
->cipher
, sop
->mac
, txform
,
292 crypto_freesession(sid
);
297 if (cmd
== CIOCGSESSION2
) {
298 /* return hardware/driver id */
299 SES2(sop
)->crid
= CRYPTO_SESID2HID(cse
->sid
);
304 kfree(crie
.cri_key
, M_XDATA
);
306 kfree(cria
.cri_key
, M_XDATA
);
310 ses
= *(u_int32_t
*)data
;
311 cse
= csefind(fcr
, ses
);
315 error
= csefree(cse
);
318 cop
= (struct crypt_op
*)data
;
319 cse
= csefind(fcr
, cop
->ses
);
322 error
= cryptodev_op(cse
, cop
, cred
);
326 if (!crypto_userasymcrypto
)
327 return (EPERM
); /* XXX compat? */
329 kop
= (struct crypt_kop
*)data
;
330 if (cmd
== CIOCKEY
) {
331 /* NB: crypto core enforces s/w driver use */
333 CRYPTOCAP_F_HARDWARE
| CRYPTOCAP_F_SOFTWARE
;
335 error
= cryptodev_key(kop
);
339 if (!crypto_userasymcrypto
) {
341 * NB: if user asym crypto operations are
342 * not permitted return "no algorithms"
343 * so well-behaved applications will just
344 * fallback to doing them in software.
348 error
= crypto_getfeat((int *)data
);
351 error
= cryptodev_find((struct crypt_find_op
*)data
);
361 static int cryptodev_cb(void *);
365 cryptodev_op(struct csession
*cse
, struct crypt_op
*cop
,
366 struct ucred
*active_cred
)
368 struct cryptop
*crp
= NULL
;
369 struct cryptodesc
*crde
= NULL
, *crda
= NULL
;
372 if (cop
->len
> 256*1024-4)
376 if (cop
->len
== 0 || (cop
->len
% cse
->txform
->blocksize
) != 0)
380 bzero(&cse
->uio
, sizeof(cse
->uio
));
381 cse
->uio
.uio_iov
= &cse
->iovec
;
382 cse
->uio
.uio_iovcnt
= 1;
383 cse
->uio
.uio_offset
= 0;
384 cse
->uio
.uio_resid
= cop
->len
;
385 cse
->uio
.uio_segflg
= UIO_SYSSPACE
;
386 cse
->uio
.uio_rw
= UIO_WRITE
;
387 /* XXX: not sure, was td, now curthread? */
388 cse
->uio
.uio_td
= curthread
;
389 cse
->uio
.uio_iov
[0].iov_len
= cop
->len
;
391 cse
->uio
.uio_iov
[0].iov_len
+= cse
->thash
->hashsize
;
392 cse
->uio
.uio_resid
+= cse
->thash
->hashsize
;
394 cse
->uio
.uio_iov
[0].iov_base
= kmalloc(cse
->uio
.uio_iov
[0].iov_len
,
397 crp
= crypto_getreq((cse
->txform
!= NULL
) + (cse
->thash
!= NULL
));
404 crda
= crp
->crp_desc
;
406 crde
= crda
->crd_next
;
409 crde
= crp
->crp_desc
;
416 if ((error
= copyin(cop
->src
, cse
->uio
.uio_iov
[0].iov_base
, cop
->len
)))
421 crda
->crd_len
= cop
->len
;
422 crda
->crd_inject
= cop
->len
;
424 crda
->crd_alg
= cse
->mac
;
425 crda
->crd_key
= cse
->mackey
;
426 crda
->crd_klen
= cse
->mackeylen
* 8;
430 if (cop
->op
== COP_ENCRYPT
)
431 crde
->crd_flags
|= CRD_F_ENCRYPT
;
433 crde
->crd_flags
&= ~CRD_F_ENCRYPT
;
434 crde
->crd_len
= cop
->len
;
435 crde
->crd_inject
= 0;
437 crde
->crd_alg
= cse
->cipher
;
438 crde
->crd_key
= cse
->key
;
439 crde
->crd_klen
= cse
->keylen
* 8;
442 crp
->crp_ilen
= cop
->len
;
443 crp
->crp_flags
= CRYPTO_F_IOV
| CRYPTO_F_CBIMM
444 | (cop
->flags
& COP_F_BATCH
);
445 crp
->crp_buf
= (caddr_t
)&cse
->uio
;
446 crp
->crp_callback
= (int (*) (struct cryptop
*)) cryptodev_cb
;
447 crp
->crp_sid
= cse
->sid
;
448 crp
->crp_opaque
= (void *)cse
;
455 if (cse
->cipher
== CRYPTO_ARC4
) { /* XXX use flag? */
459 if ((error
= copyin(cop
->iv
, cse
->tmp_iv
, cse
->txform
->blocksize
)))
461 bcopy(cse
->tmp_iv
, crde
->crd_iv
, cse
->txform
->blocksize
);
462 crde
->crd_flags
|= CRD_F_IV_EXPLICIT
| CRD_F_IV_PRESENT
;
464 } else if (cse
->cipher
== CRYPTO_ARC4
) { /* XXX use flag? */
467 crde
->crd_flags
|= CRD_F_IV_PRESENT
;
468 crde
->crd_skip
= cse
->txform
->blocksize
;
469 crde
->crd_len
-= cse
->txform
->blocksize
;
472 if (cop
->mac
&& crda
== NULL
) {
479 * Let the dispatch run unlocked, then, interlock against the
480 * callback before checking if the operation completed and going
481 * to sleep. This insures drivers don't inherit our lock which
482 * results in a lock order reversal between crypto_dispatch forced
483 * entry and the crypto_done callback into us.
485 error
= crypto_dispatch(crp
);
486 lockmgr(&cse
->lock
, LK_EXCLUSIVE
);
487 if (error
== 0 && (crp
->crp_flags
& CRYPTO_F_DONE
) == 0)
488 error
= lksleep(crp
, &cse
->lock
, 0, "crydev", 0);
489 lockmgr(&cse
->lock
, LK_RELEASE
);
494 if (crp
->crp_etype
== EAGAIN
) {
496 crp
->crp_flags
&= ~CRYPTO_F_DONE
;
500 if (crp
->crp_etype
!= 0) {
501 error
= crp
->crp_etype
;
511 (error
= copyout(cse
->uio
.uio_iov
[0].iov_base
, cop
->dst
, cop
->len
)))
515 (error
= copyout((caddr_t
)cse
->uio
.uio_iov
[0].iov_base
+ cop
->len
,
516 cop
->mac
, cse
->thash
->hashsize
)))
522 if (cse
->uio
.uio_iov
[0].iov_base
)
523 kfree(cse
->uio
.uio_iov
[0].iov_base
, M_XDATA
);
529 cryptodev_cb(void *op
)
531 struct cryptop
*crp
= (struct cryptop
*) op
;
532 struct csession
*cse
= (struct csession
*)crp
->crp_opaque
;
534 lockmgr(&cse
->lock
, LK_EXCLUSIVE
);
535 cse
->error
= crp
->crp_etype
;
537 lockmgr(&cse
->lock
, LK_RELEASE
);
542 cryptodevkey_cb(void *op
)
544 struct cryptkop
*krp
= (struct cryptkop
*) op
;
551 cryptodev_key(struct crypt_kop
*kop
)
553 struct cryptkop
*krp
= NULL
;
555 int in
, out
, size
, i
;
557 if (kop
->crk_iparams
+ kop
->crk_oparams
> CRK_MAXPARAM
) {
561 in
= kop
->crk_iparams
;
562 out
= kop
->crk_oparams
;
563 switch (kop
->crk_op
) {
565 if (in
== 3 && out
== 1)
568 case CRK_MOD_EXP_CRT
:
569 if (in
== 6 && out
== 1)
573 if (in
== 5 && out
== 2)
577 if (in
== 7 && out
== 0)
580 case CRK_DH_COMPUTE_KEY
:
581 if (in
== 3 && out
== 1)
588 krp
= (struct cryptkop
*)kmalloc(sizeof *krp
, M_XDATA
, M_WAITOK
| M_ZERO
);
589 krp
->krp_op
= kop
->crk_op
;
590 krp
->krp_status
= kop
->crk_status
;
591 krp
->krp_iparams
= kop
->crk_iparams
;
592 krp
->krp_oparams
= kop
->crk_oparams
;
593 krp
->krp_crid
= kop
->crk_crid
;
595 krp
->krp_callback
= (int (*) (struct cryptkop
*)) cryptodevkey_cb
;
597 for (i
= 0; i
< CRK_MAXPARAM
; i
++) {
598 if (kop
->crk_param
[i
].crp_nbits
> 65536)
599 /* Limit is the same as in OpenBSD */
601 krp
->krp_param
[i
].crp_nbits
= kop
->crk_param
[i
].crp_nbits
;
603 for (i
= 0; i
< krp
->krp_iparams
+ krp
->krp_oparams
; i
++) {
604 size
= (krp
->krp_param
[i
].crp_nbits
+ 7) / 8;
607 krp
->krp_param
[i
].crp_p
= kmalloc(size
, M_XDATA
, M_WAITOK
);
608 if (i
>= krp
->krp_iparams
)
610 error
= copyin(kop
->crk_param
[i
].crp_p
, krp
->krp_param
[i
].crp_p
, size
);
615 error
= crypto_kdispatch(krp
);
618 error
= tsleep(krp
, 0, "crydev", 0);
620 /* XXX can this happen? if so, how do we recover? */
624 kop
->crk_crid
= krp
->krp_crid
; /* device that did the work */
625 if (krp
->krp_status
!= 0) {
626 error
= krp
->krp_status
;
630 for (i
= krp
->krp_iparams
; i
< krp
->krp_iparams
+ krp
->krp_oparams
; i
++) {
631 size
= (krp
->krp_param
[i
].crp_nbits
+ 7) / 8;
634 error
= copyout(krp
->krp_param
[i
].crp_p
, kop
->crk_param
[i
].crp_p
, size
);
641 kop
->crk_status
= krp
->krp_status
;
642 for (i
= 0; i
< CRK_MAXPARAM
; i
++) {
643 if (krp
->krp_param
[i
].crp_p
)
644 kfree(krp
->krp_param
[i
].crp_p
, M_XDATA
);
652 cryptodev_find(struct crypt_find_op
*find
)
656 if (find
->crid
!= -1) {
657 dev
= crypto_find_device_byhid(find
->crid
);
660 strlcpy(find
->name
, device_get_nameunit(dev
),
663 find
->crid
= crypto_find_driver(find
->name
);
664 if (find
->crid
== -1)
674 cryptof_poll(struct file
*fp
, int events
, struct ucred
*active_cred
)
683 cryptof_kqfilter(struct file
*fp
, struct knote
*kn
)
693 cryptof_stat(struct file
*fp
, struct stat
*sb
, struct ucred
*cred
)
699 * MPALMOSTSAFE - acquires mplock
702 cryptof_close(struct file
*fp
)
704 struct fcrypt
*fcr
= fp
->f_data
;
705 struct csession
*cse
;
708 fcr
= (struct fcrypt
*)fp
->f_data
;
709 while ((cse
= TAILQ_FIRST(&fcr
->csessions
))) {
710 TAILQ_REMOVE(&fcr
->csessions
, cse
, next
);
720 static struct csession
*
721 csefind(struct fcrypt
*fcr
, u_int ses
)
723 struct csession
*cse
;
725 TAILQ_FOREACH(cse
, &fcr
->csessions
, next
)
732 csedelete(struct fcrypt
*fcr
, struct csession
*cse_del
)
734 struct csession
*cse
;
736 TAILQ_FOREACH(cse
, &fcr
->csessions
, next
) {
737 if (cse
== cse_del
) {
738 TAILQ_REMOVE(&fcr
->csessions
, cse
, next
);
745 static struct csession
*
746 cseadd(struct fcrypt
*fcr
, struct csession
*cse
)
748 TAILQ_INSERT_TAIL(&fcr
->csessions
, cse
, next
);
749 cse
->ses
= fcr
->sesn
++;
754 csecreate(struct fcrypt
*fcr
, u_int64_t sid
, caddr_t key
, u_int64_t keylen
,
755 caddr_t mackey
, u_int64_t mackeylen
, u_int32_t cipher
, u_int32_t mac
,
756 struct enc_xform
*txform
, struct auth_hash
*thash
)
758 struct csession
*cse
;
760 cse
= kmalloc(sizeof(struct csession
), M_XDATA
, M_NOWAIT
);
763 lockinit(&cse
->lock
, "cryptodev", 0, LK_CANRECURSE
);
765 cse
->keylen
= keylen
/8;
766 cse
->mackey
= mackey
;
767 cse
->mackeylen
= mackeylen
/8;
769 cse
->cipher
= cipher
;
771 cse
->txform
= txform
;
778 csefree(struct csession
*cse
)
782 error
= crypto_freesession(cse
->sid
);
783 lockuninit(&cse
->lock
);
785 kfree(cse
->key
, M_XDATA
);
787 kfree(cse
->mackey
, M_XDATA
);
793 cryptoopen(struct dev_open_args
*ap
)
799 cryptoread(struct dev_read_args
*ap
)
805 cryptowrite(struct dev_write_args
*ap
)
811 cryptoioctl(struct dev_ioctl_args
*ap
)
819 fcr
= kmalloc(sizeof(struct fcrypt
), M_XDATA
, M_WAITOK
);
820 TAILQ_INIT(&fcr
->csessions
);
824 error
= falloc(curproc
, &f
, &fd
);
830 /* falloc automatically provides an extra reference to 'f'. */
831 f
->f_flag
= FREAD
| FWRITE
;
832 f
->f_type
= DTYPE_CRYPTO
;
833 f
->f_ops
= &cryptofops
;
835 fsetfd(curproc
, f
, fd
);
836 *(u_int32_t
*)ap
->a_data
= fd
;
841 error
= cryptodev_find((struct crypt_find_op
*)ap
->a_data
);
844 error
= crypto_getfeat((int *)ap
->a_data
);
853 static struct dev_ops crypto_ops
= {
855 .d_open
= cryptoopen
,
856 .d_read
= cryptoread
,
857 .d_write
= cryptowrite
,
858 .d_ioctl
= cryptoioctl
,
862 * Initialization code, both for static and dynamic loading.
865 cryptodev_modevent(module_t mod
, int type
, void *unused
)
870 kprintf("crypto: <crypto device>\n");
871 make_dev(&crypto_ops
, 0, UID_ROOT
, GID_WHEEL
,
875 /*XXX disallow if active sessions */
876 //dev_ops_remove(&crypto_ops, 0, 0);
877 dev_ops_remove_all(&crypto_ops
);
883 static moduledata_t cryptodev_mod
= {
888 MODULE_VERSION(cryptodev
, 1);
889 DECLARE_MODULE(cryptodev
, cryptodev_mod
, SI_SUB_PSEUDO
, SI_ORDER_ANY
);
890 MODULE_DEPEND(cryptodev
, crypto
, 1, 1, 1);
891 MODULE_DEPEND(cryptodev
, zlib
, 1, 1, 1);