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>
54 #include <sys/file2.h>
55 #include <sys/thread2.h>
56 #include <sys/mplock2.h>
58 #include <opencrypto/cryptodev.h>
59 #include <opencrypto/xform.h>
62 TAILQ_ENTRY(csession
) next
;
68 struct enc_xform
*txform
;
70 struct auth_hash
*thash
;
74 u_char tmp_iv
[EALG_MAX_BLOCK_LEN
];
85 TAILQ_HEAD(csessionlist
, csession
) csessions
;
89 static int cryptof_rw(struct file
*fp
, struct uio
*uio
,
90 struct ucred
*cred
, int flags
);
91 static int cryptof_ioctl(struct file
*, u_long
, caddr_t
,
92 struct ucred
*, struct sysmsg
*);
93 static int cryptof_kqfilter(struct file
*, struct knote
*);
94 static int cryptof_stat(struct file
*, struct stat
*, struct ucred
*);
95 static int cryptof_close(struct file
*);
97 static struct fileops cryptofops
= {
98 .fo_read
= cryptof_rw
,
99 .fo_write
= cryptof_rw
,
100 .fo_ioctl
= cryptof_ioctl
,
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
;
189 txform
= &enc_xform_aes_xts
;
192 txform
= &enc_xform_aes_ctr
;
194 case CRYPTO_NULL_CBC
:
195 txform
= &enc_xform_null
;
198 txform
= &enc_xform_arc4
;
200 case CRYPTO_CAMELLIA_CBC
:
201 txform
= &enc_xform_camellia
;
203 case CRYPTO_TWOFISH_CBC
:
204 txform
= &enc_xform_twofish
;
206 case CRYPTO_SERPENT_CBC
:
207 txform
= &enc_xform_serpent
;
209 case CRYPTO_TWOFISH_XTS
:
210 txform
= &enc_xform_twofish_xts
;
212 case CRYPTO_SERPENT_XTS
:
213 txform
= &enc_xform_serpent_xts
;
222 case CRYPTO_MD5_HMAC
:
223 thash
= &auth_hash_hmac_md5
;
225 case CRYPTO_SHA1_HMAC
:
226 thash
= &auth_hash_hmac_sha1
;
228 case CRYPTO_SHA2_256_HMAC
:
229 thash
= &auth_hash_hmac_sha2_256
;
231 case CRYPTO_SHA2_384_HMAC
:
232 thash
= &auth_hash_hmac_sha2_384
;
234 case CRYPTO_SHA2_512_HMAC
:
235 thash
= &auth_hash_hmac_sha2_512
;
237 case CRYPTO_RIPEMD160_HMAC
:
238 thash
= &auth_hash_hmac_ripemd_160
;
242 thash
= &auth_hash_md5
;
245 thash
= &auth_hash_sha1
;
248 case CRYPTO_NULL_HMAC
:
249 thash
= &auth_hash_null
;
255 bzero(&crie
, sizeof(crie
));
256 bzero(&cria
, sizeof(cria
));
259 crie
.cri_alg
= txform
->type
;
260 crie
.cri_klen
= sop
->keylen
* 8;
261 if (sop
->keylen
> txform
->maxkey
||
262 sop
->keylen
< txform
->minkey
) {
267 crie
.cri_key
= kmalloc(crie
.cri_klen
/ 8,
269 if ((error
= copyin(sop
->key
, crie
.cri_key
,
273 crie
.cri_next
= &cria
;
277 cria
.cri_alg
= thash
->type
;
278 cria
.cri_klen
= sop
->mackeylen
* 8;
279 if (sop
->mackeylen
!= thash
->keysize
) {
285 cria
.cri_key
= kmalloc(cria
.cri_klen
/ 8,
287 if ((error
= copyin(sop
->mackey
, cria
.cri_key
,
293 /* NB: CIOGSESSION2 has the crid */
294 if (cmd
== CIOCGSESSION2
) {
295 crid
= SES2(sop
)->crid
;
296 error
= checkforsoftware(crid
);
300 crid
= CRYPTOCAP_F_HARDWARE
;
301 if (crypto_devallowsoft
)
302 crid
|= CRYPTOCAP_F_SOFTWARE
;
304 error
= crypto_newsession(&sid
, (txform
? &crie
: &cria
), crid
);
308 cse
= csecreate(fcr
, sid
, crie
.cri_key
, crie
.cri_klen
,
309 cria
.cri_key
, cria
.cri_klen
, sop
->cipher
, sop
->mac
, txform
,
313 crypto_freesession(sid
);
318 if (cmd
== CIOCGSESSION2
) {
319 /* return hardware/driver id */
320 SES2(sop
)->crid
= CRYPTO_SESID2HID(cse
->sid
);
325 bzero(crie
.cri_key
, crie
.cri_klen
/ 8);
326 kfree(crie
.cri_key
, M_XDATA
);
329 bzero(cria
.cri_key
, cria
.cri_klen
/ 8);
330 kfree(cria
.cri_key
, M_XDATA
);
335 ses
= *(u_int32_t
*)data
;
336 cse
= csefind(fcr
, ses
);
340 error
= csefree(cse
);
343 cop
= (struct crypt_op
*)data
;
344 cse
= csefind(fcr
, cop
->ses
);
347 error
= cryptodev_op(cse
, cop
, cred
);
351 if (!crypto_userasymcrypto
)
352 return (EPERM
); /* XXX compat? */
354 kop
= (struct crypt_kop
*)data
;
355 if (cmd
== CIOCKEY
) {
356 /* NB: crypto core enforces s/w driver use */
358 CRYPTOCAP_F_HARDWARE
| CRYPTOCAP_F_SOFTWARE
;
360 error
= cryptodev_key(kop
);
364 if (!crypto_userasymcrypto
) {
366 * NB: if user asym crypto operations are
367 * not permitted return "no algorithms"
368 * so well-behaved applications will just
369 * fallback to doing them in software.
373 error
= crypto_getfeat((int *)data
);
376 error
= cryptodev_find((struct crypt_find_op
*)data
);
386 static int cryptodev_cb(void *);
390 cryptodev_op(struct csession
*cse
, struct crypt_op
*cop
,
391 struct ucred
*active_cred
)
393 struct cryptop
*crp
= NULL
;
394 struct cryptodesc
*crde
= NULL
, *crda
= NULL
;
397 if (cop
->len
> 256*1024-4)
401 if (cop
->len
== 0 || (cop
->len
% cse
->txform
->blocksize
) != 0)
405 bzero(&cse
->uio
, sizeof(cse
->uio
));
406 cse
->uio
.uio_iov
= &cse
->iovec
;
407 cse
->uio
.uio_iovcnt
= 1;
408 cse
->uio
.uio_offset
= 0;
409 cse
->uio
.uio_resid
= cop
->len
;
410 cse
->uio
.uio_segflg
= UIO_SYSSPACE
;
411 cse
->uio
.uio_rw
= UIO_WRITE
;
412 /* XXX: not sure, was td, now curthread? */
413 cse
->uio
.uio_td
= curthread
;
414 cse
->uio
.uio_iov
[0].iov_len
= cop
->len
;
416 cse
->uio
.uio_iov
[0].iov_len
+= cse
->thash
->hashsize
;
417 cse
->uio
.uio_resid
+= cse
->thash
->hashsize
;
419 cse
->uio
.uio_iov
[0].iov_base
= kmalloc(cse
->uio
.uio_iov
[0].iov_len
,
422 crp
= crypto_getreq((cse
->txform
!= NULL
) + (cse
->thash
!= NULL
));
429 crda
= crp
->crp_desc
;
431 crde
= crda
->crd_next
;
434 crde
= crp
->crp_desc
;
441 if ((error
= copyin(cop
->src
, cse
->uio
.uio_iov
[0].iov_base
, cop
->len
)))
446 crda
->crd_len
= cop
->len
;
447 crda
->crd_inject
= cop
->len
;
449 crda
->crd_alg
= cse
->mac
;
450 crda
->crd_key
= cse
->mackey
;
451 crda
->crd_klen
= cse
->mackeylen
* 8;
455 if (cop
->op
== COP_ENCRYPT
)
456 crde
->crd_flags
|= CRD_F_ENCRYPT
;
458 crde
->crd_flags
&= ~CRD_F_ENCRYPT
;
459 crde
->crd_len
= cop
->len
;
460 crde
->crd_inject
= 0;
462 crde
->crd_alg
= cse
->cipher
;
463 crde
->crd_key
= cse
->key
;
464 crde
->crd_klen
= cse
->keylen
* 8;
467 crp
->crp_ilen
= cop
->len
;
468 crp
->crp_flags
= CRYPTO_F_IOV
| CRYPTO_F_CBIMM
469 | (cop
->flags
& COP_F_BATCH
);
470 crp
->crp_buf
= (caddr_t
)&cse
->uio
;
471 crp
->crp_callback
= (int (*) (struct cryptop
*)) cryptodev_cb
;
472 crp
->crp_sid
= cse
->sid
;
473 crp
->crp_opaque
= (void *)cse
;
480 if (cse
->cipher
== CRYPTO_ARC4
) { /* XXX use flag? */
484 if ((error
= copyin(cop
->iv
, cse
->tmp_iv
, cse
->txform
->blocksize
)))
486 bcopy(cse
->tmp_iv
, crde
->crd_iv
, cse
->txform
->blocksize
);
487 crde
->crd_flags
|= CRD_F_IV_EXPLICIT
| CRD_F_IV_PRESENT
;
489 } else if (cse
->cipher
== CRYPTO_ARC4
) { /* XXX use flag? */
492 crde
->crd_flags
|= CRD_F_IV_PRESENT
;
493 crde
->crd_skip
= cse
->txform
->blocksize
;
494 crde
->crd_len
-= cse
->txform
->blocksize
;
497 if (cop
->mac
&& crda
== NULL
) {
504 * Let the dispatch run unlocked, then, interlock against the
505 * callback before checking if the operation completed and going
506 * to sleep. This insures drivers don't inherit our lock which
507 * results in a lock order reversal between crypto_dispatch forced
508 * entry and the crypto_done callback into us.
510 error
= crypto_dispatch(crp
);
511 lockmgr(&cse
->lock
, LK_EXCLUSIVE
);
512 if (error
== 0 && (crp
->crp_flags
& CRYPTO_F_DONE
) == 0)
513 error
= lksleep(crp
, &cse
->lock
, 0, "crydev", 0);
514 lockmgr(&cse
->lock
, LK_RELEASE
);
519 if (crp
->crp_etype
== EAGAIN
) {
521 crp
->crp_flags
&= ~CRYPTO_F_DONE
;
525 if (crp
->crp_etype
!= 0) {
526 error
= crp
->crp_etype
;
536 (error
= copyout(cse
->uio
.uio_iov
[0].iov_base
, cop
->dst
, cop
->len
)))
540 (error
= copyout((caddr_t
)cse
->uio
.uio_iov
[0].iov_base
+ cop
->len
,
541 cop
->mac
, cse
->thash
->hashsize
)))
547 if (cse
->uio
.uio_iov
[0].iov_base
)
548 kfree(cse
->uio
.uio_iov
[0].iov_base
, M_XDATA
);
554 cryptodev_cb(void *op
)
556 struct cryptop
*crp
= (struct cryptop
*) op
;
557 struct csession
*cse
= (struct csession
*)crp
->crp_opaque
;
559 lockmgr(&cse
->lock
, LK_EXCLUSIVE
);
560 cse
->error
= crp
->crp_etype
;
562 lockmgr(&cse
->lock
, LK_RELEASE
);
567 cryptodevkey_cb(void *op
)
569 struct cryptkop
*krp
= (struct cryptkop
*) op
;
576 cryptodev_key(struct crypt_kop
*kop
)
578 struct cryptkop
*krp
= NULL
;
580 int in
, out
, size
, i
;
582 if (kop
->crk_iparams
+ kop
->crk_oparams
> CRK_MAXPARAM
) {
586 in
= kop
->crk_iparams
;
587 out
= kop
->crk_oparams
;
588 switch (kop
->crk_op
) {
590 if (in
== 3 && out
== 1)
593 case CRK_MOD_EXP_CRT
:
594 if (in
== 6 && out
== 1)
598 if (in
== 5 && out
== 2)
602 if (in
== 7 && out
== 0)
605 case CRK_DH_COMPUTE_KEY
:
606 if (in
== 3 && out
== 1)
613 krp
= (struct cryptkop
*)kmalloc(sizeof *krp
, M_XDATA
, M_WAITOK
| M_ZERO
);
614 krp
->krp_op
= kop
->crk_op
;
615 krp
->krp_status
= kop
->crk_status
;
616 krp
->krp_iparams
= kop
->crk_iparams
;
617 krp
->krp_oparams
= kop
->crk_oparams
;
618 krp
->krp_crid
= kop
->crk_crid
;
620 krp
->krp_callback
= (int (*) (struct cryptkop
*)) cryptodevkey_cb
;
622 for (i
= 0; i
< CRK_MAXPARAM
; i
++) {
623 if (kop
->crk_param
[i
].crp_nbits
> 65536)
624 /* Limit is the same as in OpenBSD */
626 krp
->krp_param
[i
].crp_nbits
= kop
->crk_param
[i
].crp_nbits
;
628 for (i
= 0; i
< krp
->krp_iparams
+ krp
->krp_oparams
; i
++) {
629 size
= (krp
->krp_param
[i
].crp_nbits
+ 7) / 8;
632 krp
->krp_param
[i
].crp_p
= kmalloc(size
, M_XDATA
, M_WAITOK
);
633 if (i
>= krp
->krp_iparams
)
635 error
= copyin(kop
->crk_param
[i
].crp_p
, krp
->krp_param
[i
].crp_p
, size
);
640 error
= crypto_kdispatch(krp
);
643 error
= tsleep(krp
, 0, "crydev", 0);
645 /* XXX can this happen? if so, how do we recover? */
649 kop
->crk_crid
= krp
->krp_crid
; /* device that did the work */
650 if (krp
->krp_status
!= 0) {
651 error
= krp
->krp_status
;
655 for (i
= krp
->krp_iparams
; i
< krp
->krp_iparams
+ krp
->krp_oparams
; i
++) {
656 size
= (krp
->krp_param
[i
].crp_nbits
+ 7) / 8;
659 error
= copyout(krp
->krp_param
[i
].crp_p
, kop
->crk_param
[i
].crp_p
, size
);
666 kop
->crk_status
= krp
->krp_status
;
667 for (i
= 0; i
< CRK_MAXPARAM
; i
++) {
668 if (krp
->krp_param
[i
].crp_p
) {
669 bzero(krp
->krp_param
[i
].crp_p
,
670 (krp
->krp_param
[i
].crp_nbits
+ 7) / 8);
671 kfree(krp
->krp_param
[i
].crp_p
, M_XDATA
);
680 cryptodev_find(struct crypt_find_op
*find
)
684 if (find
->crid
!= -1) {
685 dev
= crypto_find_device_byhid(find
->crid
);
688 strlcpy(find
->name
, device_get_nameunit(dev
),
691 find
->crid
= crypto_find_driver(find
->name
);
692 if (find
->crid
== -1)
702 cryptof_kqfilter(struct file
*fp
, struct knote
*kn
)
712 cryptof_stat(struct file
*fp
, struct stat
*sb
, struct ucred
*cred
)
718 * MPALMOSTSAFE - acquires mplock
721 cryptof_close(struct file
*fp
)
723 struct fcrypt
*fcr
= fp
->f_data
;
724 struct csession
*cse
;
727 fcr
= (struct fcrypt
*)fp
->f_data
;
728 while ((cse
= TAILQ_FIRST(&fcr
->csessions
))) {
729 TAILQ_REMOVE(&fcr
->csessions
, cse
, next
);
739 static struct csession
*
740 csefind(struct fcrypt
*fcr
, u_int ses
)
742 struct csession
*cse
;
744 TAILQ_FOREACH(cse
, &fcr
->csessions
, next
)
751 csedelete(struct fcrypt
*fcr
, struct csession
*cse_del
)
753 struct csession
*cse
;
755 TAILQ_FOREACH(cse
, &fcr
->csessions
, next
) {
756 if (cse
== cse_del
) {
757 TAILQ_REMOVE(&fcr
->csessions
, cse
, next
);
764 static struct csession
*
765 cseadd(struct fcrypt
*fcr
, struct csession
*cse
)
767 TAILQ_INSERT_TAIL(&fcr
->csessions
, cse
, next
);
768 cse
->ses
= fcr
->sesn
++;
773 csecreate(struct fcrypt
*fcr
, u_int64_t sid
, caddr_t key
, u_int64_t keylen
,
774 caddr_t mackey
, u_int64_t mackeylen
, u_int32_t cipher
, u_int32_t mac
,
775 struct enc_xform
*txform
, struct auth_hash
*thash
)
777 struct csession
*cse
;
779 cse
= kmalloc(sizeof(struct csession
), M_XDATA
, M_WAITOK
| M_ZERO
);
780 lockinit(&cse
->lock
, "cryptodev", 0, LK_CANRECURSE
);
782 cse
->keylen
= keylen
/8;
783 cse
->mackey
= mackey
;
784 cse
->mackeylen
= mackeylen
/8;
786 cse
->cipher
= cipher
;
788 cse
->txform
= txform
;
795 csefree(struct csession
*cse
)
799 error
= crypto_freesession(cse
->sid
);
800 lockuninit(&cse
->lock
);
802 kfree(cse
->key
, M_XDATA
);
804 kfree(cse
->mackey
, M_XDATA
);
810 cryptoopen(struct dev_open_args
*ap
)
816 cryptoread(struct dev_read_args
*ap
)
822 cryptowrite(struct dev_write_args
*ap
)
828 cryptoioctl(struct dev_ioctl_args
*ap
)
830 struct thread
*td
= curthread
;
837 fcr
= kmalloc(sizeof(struct fcrypt
), M_XDATA
, M_WAITOK
);
838 TAILQ_INIT(&fcr
->csessions
);
841 KKASSERT(td
->td_lwp
);
842 error
= falloc(td
->td_lwp
, &f
, &fd
);
848 /* falloc automatically provides an extra reference to 'f'. */
849 f
->f_flag
= FREAD
| FWRITE
;
850 f
->f_type
= DTYPE_CRYPTO
;
851 f
->f_ops
= &cryptofops
;
853 fsetfd(td
->td_proc
->p_fd
, f
, fd
);
854 *(u_int32_t
*)ap
->a_data
= fd
;
859 error
= cryptodev_find((struct crypt_find_op
*)ap
->a_data
);
862 error
= crypto_getfeat((int *)ap
->a_data
);
871 static struct dev_ops crypto_ops
= {
872 { "crypto", 0, D_MPSAFE
},
873 .d_open
= cryptoopen
,
874 .d_read
= cryptoread
,
875 .d_write
= cryptowrite
,
876 .d_ioctl
= cryptoioctl
,
880 * Initialization code, both for static and dynamic loading.
883 cryptodev_modevent(module_t mod
, int type
, void *unused
)
888 kprintf("crypto: <crypto device>\n");
889 make_dev(&crypto_ops
, 0, UID_ROOT
, GID_WHEEL
,
893 /*XXX disallow if active sessions */
894 //dev_ops_remove(&crypto_ops, 0, 0);
895 dev_ops_remove_all(&crypto_ops
);
901 static moduledata_t cryptodev_mod
= {
906 MODULE_VERSION(cryptodev
, 1);
907 DECLARE_MODULE(cryptodev
, cryptodev_mod
, SI_SUB_PSEUDO
, SI_ORDER_ANY
);
908 MODULE_DEPEND(cryptodev
, crypto
, 1, 1, 1);