Deleted Added
full compact
cryptodev.c (158831) cryptodev.c (167755)
1/* $OpenBSD: cryptodev.c,v 1.52 2002/06/19 07:22:46 deraadt Exp $ */
2
3/*-
4 * Copyright (c) 2001 Theo de Raadt
1/* $OpenBSD: cryptodev.c,v 1.52 2002/06/19 07:22:46 deraadt Exp $ */
2
3/*-
4 * Copyright (c) 2001 Theo de Raadt
5 * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright

--- 14 unchanged lines hidden (view full) ---

27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Effort sponsored in part by the Defense Advanced Research Projects
30 * Agency (DARPA) and Air Force Research Laboratory, Air Force
31 * Materiel Command, USAF, under agreement number F30602-01-2-0537.
32 */
33
34#include <sys/cdefs.h>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright

--- 14 unchanged lines hidden (view full) ---

28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * Effort sponsored in part by the Defense Advanced Research Projects
31 * Agency (DARPA) and Air Force Research Laboratory, Air Force
32 * Materiel Command, USAF, under agreement number F30602-01-2-0537.
33 */
34
35#include <sys/cdefs.h>
35__FBSDID("$FreeBSD: head/sys/opencrypto/cryptodev.c 158831 2006-05-22 16:24:11Z pjd $");
36__FBSDID("$FreeBSD: head/sys/opencrypto/cryptodev.c 167755 2007-03-21 03:42:51Z sam $");
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/malloc.h>
40#include <sys/mbuf.h>
41#include <sys/lock.h>
42#include <sys/mutex.h>
43#include <sys/sysctl.h>
44#include <sys/file.h>
45#include <sys/filedesc.h>
46#include <sys/errno.h>
47#include <sys/uio.h>
48#include <sys/random.h>
49#include <sys/conf.h>
50#include <sys/kernel.h>
51#include <sys/module.h>
52#include <sys/fcntl.h>
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/malloc.h>
41#include <sys/mbuf.h>
42#include <sys/lock.h>
43#include <sys/mutex.h>
44#include <sys/sysctl.h>
45#include <sys/file.h>
46#include <sys/filedesc.h>
47#include <sys/errno.h>
48#include <sys/uio.h>
49#include <sys/random.h>
50#include <sys/conf.h>
51#include <sys/kernel.h>
52#include <sys/module.h>
53#include <sys/fcntl.h>
54#include <sys/bus.h>
53
54#include <opencrypto/cryptodev.h>
55#include <opencrypto/xform.h>
56
57struct csession {
58 TAILQ_ENTRY(csession) next;
59 u_int64_t sid;
60 u_int32_t ses;

--- 47 unchanged lines hidden (view full) ---

108static struct csession *csecreate(struct fcrypt *, u_int64_t, caddr_t,
109 u_int64_t, caddr_t, u_int64_t, u_int32_t, u_int32_t, struct enc_xform *,
110 struct auth_hash *);
111static int csefree(struct csession *);
112
113static int cryptodev_op(struct csession *, struct crypt_op *,
114 struct ucred *, struct thread *td);
115static int cryptodev_key(struct crypt_kop *);
55
56#include <opencrypto/cryptodev.h>
57#include <opencrypto/xform.h>
58
59struct csession {
60 TAILQ_ENTRY(csession) next;
61 u_int64_t sid;
62 u_int32_t ses;

--- 47 unchanged lines hidden (view full) ---

110static 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 *,
112 struct auth_hash *);
113static int csefree(struct csession *);
114
115static int cryptodev_op(struct csession *, struct crypt_op *,
116 struct ucred *, struct thread *td);
117static int cryptodev_key(struct crypt_kop *);
118static int cryptodev_find(struct crypt_find_op *);
116
117static int
118cryptof_rw(
119 struct file *fp,
120 struct uio *uio,
121 struct ucred *active_cred,
122 int flags,
123 struct thread *td)
124{
125
126 return (EIO);
127}
128
119
120static int
121cryptof_rw(
122 struct file *fp,
123 struct uio *uio,
124 struct ucred *active_cred,
125 int flags,
126 struct thread *td)
127{
128
129 return (EIO);
130}
131
132/*
133 * Check a crypto identifier to see if it requested
134 * a software device/driver. This can be done either
135 * by device name/class or through search constraints.
136 */
137static int
138checkforsoftware(int crid)
139{
140 if (crid & CRYPTOCAP_F_SOFTWARE)
141 return EINVAL; /* XXX */
142 if ((crid & CRYPTOCAP_F_HARDWARE) == 0 &&
143 (crypto_getcaps(crid) & CRYPTOCAP_F_HARDWARE) == 0)
144 return EINVAL; /* XXX */
145 return 0;
146}
147
129/* ARGSUSED */
130static int
131cryptof_ioctl(
132 struct file *fp,
133 u_long cmd,
134 void *data,
135 struct ucred *active_cred,
136 struct thread *td)
137{
148/* ARGSUSED */
149static int
150cryptof_ioctl(
151 struct file *fp,
152 u_long cmd,
153 void *data,
154 struct ucred *active_cred,
155 struct thread *td)
156{
157#define SES2(p) ((struct session2_op *)p)
138 struct cryptoini cria, crie;
139 struct fcrypt *fcr = fp->f_data;
140 struct csession *cse;
141 struct session_op *sop;
142 struct crypt_op *cop;
143 struct enc_xform *txform = NULL;
144 struct auth_hash *thash = NULL;
158 struct cryptoini cria, crie;
159 struct fcrypt *fcr = fp->f_data;
160 struct csession *cse;
161 struct session_op *sop;
162 struct crypt_op *cop;
163 struct enc_xform *txform = NULL;
164 struct auth_hash *thash = NULL;
165 struct crypt_kop *kop;
145 u_int64_t sid;
146 u_int32_t ses;
166 u_int64_t sid;
167 u_int32_t ses;
147 int error = 0;
168 int error = 0, crid;
148
169
149 /*
150 * XXX: Not sure Giant is needed, but better safe than sorry
151 */
152 mtx_lock(&Giant);
153 switch (cmd) {
154 case CIOCGSESSION:
170 switch (cmd) {
171 case CIOCGSESSION:
172 case CIOCGSESSION2:
155 sop = (struct session_op *)data;
156 switch (sop->cipher) {
157 case 0:
158 break;
159 case CRYPTO_DES_CBC:
160 txform = &enc_xform_des;
161 break;
162 case CRYPTO_3DES_CBC:

--- 13 unchanged lines hidden (view full) ---

176 break;
177 case CRYPTO_NULL_CBC:
178 txform = &enc_xform_null;
179 break;
180 case CRYPTO_ARC4:
181 txform = &enc_xform_arc4;
182 break;
183 default:
173 sop = (struct session_op *)data;
174 switch (sop->cipher) {
175 case 0:
176 break;
177 case CRYPTO_DES_CBC:
178 txform = &enc_xform_des;
179 break;
180 case CRYPTO_3DES_CBC:

--- 13 unchanged lines hidden (view full) ---

194 break;
195 case CRYPTO_NULL_CBC:
196 txform = &enc_xform_null;
197 break;
198 case CRYPTO_ARC4:
199 txform = &enc_xform_arc4;
200 break;
201 default:
184 mtx_unlock(&Giant);
185 return (EINVAL);
186 }
187
188 switch (sop->mac) {
189 case 0:
190 break;
191 case CRYPTO_MD5_HMAC:
192 thash = &auth_hash_hmac_md5;

--- 20 unchanged lines hidden (view full) ---

213 case CRYPTO_SHA1:
214 thash = &auth_hash_sha1;
215 break;
216#endif
217 case CRYPTO_NULL_HMAC:
218 thash = &auth_hash_null;
219 break;
220 default:
202 return (EINVAL);
203 }
204
205 switch (sop->mac) {
206 case 0:
207 break;
208 case CRYPTO_MD5_HMAC:
209 thash = &auth_hash_hmac_md5;

--- 20 unchanged lines hidden (view full) ---

230 case CRYPTO_SHA1:
231 thash = &auth_hash_sha1;
232 break;
233#endif
234 case CRYPTO_NULL_HMAC:
235 thash = &auth_hash_null;
236 break;
237 default:
221 mtx_unlock(&Giant);
222 return (EINVAL);
223 }
224
225 bzero(&crie, sizeof(crie));
226 bzero(&cria, sizeof(cria));
227
228 if (txform) {
229 crie.cri_alg = txform->type;

--- 25 unchanged lines hidden (view full) ---

255 MALLOC(cria.cri_key, u_int8_t *,
256 cria.cri_klen / 8, M_XDATA, M_WAITOK);
257 if ((error = copyin(sop->mackey, cria.cri_key,
258 cria.cri_klen / 8)))
259 goto bail;
260 }
261 }
262
238 return (EINVAL);
239 }
240
241 bzero(&crie, sizeof(crie));
242 bzero(&cria, sizeof(cria));
243
244 if (txform) {
245 crie.cri_alg = txform->type;

--- 25 unchanged lines hidden (view full) ---

271 MALLOC(cria.cri_key, u_int8_t *,
272 cria.cri_klen / 8, M_XDATA, M_WAITOK);
273 if ((error = copyin(sop->mackey, cria.cri_key,
274 cria.cri_klen / 8)))
275 goto bail;
276 }
277 }
278
263 error = crypto_newsession(&sid, (txform ? &crie : &cria), 1);
264 if (error) {
265 if (crypto_devallowsoft) {
266 error = crypto_newsession(&sid,
267 (txform ? &crie : &cria), 0);
268 }
279 /* NB: CIOGSESSION2 has the crid */
280 if (cmd == CIOCGSESSION2) {
281 crid = SES2(sop)->crid;
282 error = checkforsoftware(crid);
269 if (error)
270 goto bail;
283 if (error)
284 goto bail;
271 }
285 } else
286 crid = CRYPTOCAP_F_HARDWARE;
287 error = crypto_newsession(&sid, (txform ? &crie : &cria), crid);
288 if (error)
289 goto bail;
272
273 cse = csecreate(fcr, sid, crie.cri_key, crie.cri_klen,
274 cria.cri_key, cria.cri_klen, sop->cipher, sop->mac, txform,
275 thash);
276
277 if (cse == NULL) {
278 crypto_freesession(sid);
279 error = EINVAL;
280 goto bail;
281 }
282 sop->ses = cse->ses;
290
291 cse = csecreate(fcr, sid, crie.cri_key, crie.cri_klen,
292 cria.cri_key, cria.cri_klen, sop->cipher, sop->mac, txform,
293 thash);
294
295 if (cse == NULL) {
296 crypto_freesession(sid);
297 error = EINVAL;
298 goto bail;
299 }
300 sop->ses = cse->ses;
283
301 if (cmd == CIOCGSESSION2) {
302 /* return hardware/driver id */
303 SES2(sop)->crid = CRYPTO_SESID2HID(cse->sid);
304 }
284bail:
285 if (error) {
286 if (crie.cri_key)
287 FREE(crie.cri_key, M_XDATA);
288 if (cria.cri_key)
289 FREE(cria.cri_key, M_XDATA);
290 }
291 break;
292 case CIOCFSESSION:
293 ses = *(u_int32_t *)data;
294 cse = csefind(fcr, ses);
305bail:
306 if (error) {
307 if (crie.cri_key)
308 FREE(crie.cri_key, M_XDATA);
309 if (cria.cri_key)
310 FREE(cria.cri_key, M_XDATA);
311 }
312 break;
313 case CIOCFSESSION:
314 ses = *(u_int32_t *)data;
315 cse = csefind(fcr, ses);
295 if (cse == NULL) {
296 mtx_unlock(&Giant);
316 if (cse == NULL)
297 return (EINVAL);
317 return (EINVAL);
298 }
299 csedelete(fcr, cse);
300 error = csefree(cse);
301 break;
302 case CIOCCRYPT:
303 cop = (struct crypt_op *)data;
304 cse = csefind(fcr, cop->ses);
318 csedelete(fcr, cse);
319 error = csefree(cse);
320 break;
321 case CIOCCRYPT:
322 cop = (struct crypt_op *)data;
323 cse = csefind(fcr, cop->ses);
305 if (cse == NULL) {
306 mtx_unlock(&Giant);
324 if (cse == NULL)
307 return (EINVAL);
325 return (EINVAL);
308 }
309 error = cryptodev_op(cse, cop, active_cred, td);
310 break;
311 case CIOCKEY:
326 error = cryptodev_op(cse, cop, active_cred, td);
327 break;
328 case CIOCKEY:
312 error = cryptodev_key((struct crypt_kop *)data);
329 case CIOCKEY2:
330 if (!crypto_userasymcrypto)
331 return (EPERM); /* XXX compat? */
332 mtx_lock(&Giant);
333 kop = (struct crypt_kop *)data;
334 if (cmd == CIOCKEY) {
335 /* NB: crypto core enforces s/w driver use */
336 kop->crk_crid =
337 CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
338 }
339 error = cryptodev_key(kop);
340 mtx_unlock(&Giant);
313 break;
314 case CIOCASYMFEAT:
341 break;
342 case CIOCASYMFEAT:
315 error = crypto_getfeat((int *)data);
343 if (!crypto_userasymcrypto) {
344 /*
345 * NB: if user asym crypto operations are
346 * not permitted return "no algorithms"
347 * so well-behaved applications will just
348 * fallback to doing them in software.
349 */
350 *(int *)data = 0;
351 } else
352 error = crypto_getfeat((int *)data);
316 break;
353 break;
354 case CIOCFINDDEV:
355 error = cryptodev_find((struct crypt_find_op *)data);
356 break;
317 default:
318 error = EINVAL;
357 default:
358 error = EINVAL;
359 break;
319 }
360 }
320 mtx_unlock(&Giant);
321 return (error);
361 return (error);
362#undef SES2
322}
323
324static int cryptodev_cb(void *);
325
326
327static int
328cryptodev_op(
329 struct csession *cse,

--- 150 unchanged lines hidden (view full) ---

480 return (error);
481}
482
483static int
484cryptodev_cb(void *op)
485{
486 struct cryptop *crp = (struct cryptop *) op;
487 struct csession *cse = (struct csession *)crp->crp_opaque;
363}
364
365static int cryptodev_cb(void *);
366
367
368static int
369cryptodev_op(
370 struct csession *cse,

--- 150 unchanged lines hidden (view full) ---

521 return (error);
522}
523
524static int
525cryptodev_cb(void *op)
526{
527 struct cryptop *crp = (struct cryptop *) op;
528 struct csession *cse = (struct csession *)crp->crp_opaque;
529 int error;
488
530
489 cse->error = crp->crp_etype;
490 if (crp->crp_etype == EAGAIN)
491 return crypto_dispatch(crp);
531 error = crp->crp_etype;
532 if (error == EAGAIN)
533 error = crypto_dispatch(crp);
492 mtx_lock(&cse->lock);
534 mtx_lock(&cse->lock);
493 wakeup_one(crp);
535 if (error != 0 || (crp->crp_flags & CRYPTO_F_DONE)) {
536 cse->error = error;
537 wakeup_one(crp);
538 }
494 mtx_unlock(&cse->lock);
495 return (0);
496}
497
498static int
499cryptodevkey_cb(void *op)
500{
501 struct cryptkop *krp = (struct cryptkop *) op;
502
539 mtx_unlock(&cse->lock);
540 return (0);
541}
542
543static int
544cryptodevkey_cb(void *op)
545{
546 struct cryptkop *krp = (struct cryptkop *) op;
547
503 wakeup(krp);
548 wakeup_one(krp);
504 return (0);
505}
506
507static int
508cryptodev_key(struct crypt_kop *kop)
509{
510 struct cryptkop *krp = NULL;
511 int error = EINVAL;

--- 33 unchanged lines hidden (view full) ---

545 krp = (struct cryptkop *)malloc(sizeof *krp, M_XDATA, M_WAITOK);
546 if (!krp)
547 return (ENOMEM);
548 bzero(krp, sizeof *krp);
549 krp->krp_op = kop->crk_op;
550 krp->krp_status = kop->crk_status;
551 krp->krp_iparams = kop->crk_iparams;
552 krp->krp_oparams = kop->crk_oparams;
549 return (0);
550}
551
552static int
553cryptodev_key(struct crypt_kop *kop)
554{
555 struct cryptkop *krp = NULL;
556 int error = EINVAL;

--- 33 unchanged lines hidden (view full) ---

590 krp = (struct cryptkop *)malloc(sizeof *krp, M_XDATA, M_WAITOK);
591 if (!krp)
592 return (ENOMEM);
593 bzero(krp, sizeof *krp);
594 krp->krp_op = kop->crk_op;
595 krp->krp_status = kop->crk_status;
596 krp->krp_iparams = kop->crk_iparams;
597 krp->krp_oparams = kop->crk_oparams;
598 krp->krp_crid = kop->crk_crid;
553 krp->krp_status = 0;
554 krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb;
555
556 for (i = 0; i < CRK_MAXPARAM; i++)
557 krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits;
558 for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) {
559 size = (krp->krp_param[i].crp_nbits + 7) / 8;
560 if (size == 0)

--- 10 unchanged lines hidden (view full) ---

571 if (error)
572 goto fail;
573 error = tsleep(krp, PSOCK, "crydev", 0);
574 if (error) {
575 /* XXX can this happen? if so, how do we recover? */
576 goto fail;
577 }
578
599 krp->krp_status = 0;
600 krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb;
601
602 for (i = 0; i < CRK_MAXPARAM; i++)
603 krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits;
604 for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) {
605 size = (krp->krp_param[i].crp_nbits + 7) / 8;
606 if (size == 0)

--- 10 unchanged lines hidden (view full) ---

617 if (error)
618 goto fail;
619 error = tsleep(krp, PSOCK, "crydev", 0);
620 if (error) {
621 /* XXX can this happen? if so, how do we recover? */
622 goto fail;
623 }
624
625 kop->crk_crid = krp->krp_crid; /* device that did the work */
579 if (krp->krp_status != 0) {
580 error = krp->krp_status;
581 goto fail;
582 }
583
584 for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) {
585 size = (krp->krp_param[i].crp_nbits + 7) / 8;
586 if (size == 0)

--- 10 unchanged lines hidden (view full) ---

597 if (krp->krp_param[i].crp_p)
598 FREE(krp->krp_param[i].crp_p, M_XDATA);
599 }
600 free(krp, M_XDATA);
601 }
602 return (error);
603}
604
626 if (krp->krp_status != 0) {
627 error = krp->krp_status;
628 goto fail;
629 }
630
631 for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) {
632 size = (krp->krp_param[i].crp_nbits + 7) / 8;
633 if (size == 0)

--- 10 unchanged lines hidden (view full) ---

644 if (krp->krp_param[i].crp_p)
645 FREE(krp->krp_param[i].crp_p, M_XDATA);
646 }
647 free(krp, M_XDATA);
648 }
649 return (error);
650}
651
652static int
653cryptodev_find(struct crypt_find_op *find)
654{
655 device_t dev;
656
657 if (find->crid != -1) {
658 dev = crypto_find_device_byhid(find->crid);
659 if (dev == NULL)
660 return (ENOENT);
661 strlcpy(find->name, device_get_nameunit(dev),
662 sizeof(find->name));
663 } else {
664 find->crid = crypto_find_driver(find->name);
665 if (find->crid == -1)
666 return (ENOENT);
667 }
668 return (0);
669}
670
605/* ARGSUSED */
606static int
607cryptof_poll(
608 struct file *fp,
609 int events,
610 struct ucred *active_cred,
611 struct thread *td)
612{

--- 157 unchanged lines hidden (view full) ---

770 /* falloc automatically provides an extra reference to 'f'. */
771 f->f_flag = FREAD | FWRITE;
772 f->f_type = DTYPE_CRYPTO;
773 f->f_ops = &cryptofops;
774 f->f_data = fcr;
775 *(u_int32_t *)data = fd;
776 fdrop(f, td);
777 break;
671/* ARGSUSED */
672static int
673cryptof_poll(
674 struct file *fp,
675 int events,
676 struct ucred *active_cred,
677 struct thread *td)
678{

--- 157 unchanged lines hidden (view full) ---

836 /* falloc automatically provides an extra reference to 'f'. */
837 f->f_flag = FREAD | FWRITE;
838 f->f_type = DTYPE_CRYPTO;
839 f->f_ops = &cryptofops;
840 f->f_data = fcr;
841 *(u_int32_t *)data = fd;
842 fdrop(f, td);
843 break;
844 case CRIOFINDDEV:
845 error = cryptodev_find((struct crypt_find_op *)data);
846 break;
847 case CRIOASYMFEAT:
848 error = crypto_getfeat((int *)data);
849 break;
778 default:
779 error = EINVAL;
780 break;
781 }
782 return (error);
783}
784
785static struct cdevsw crypto_cdevsw = {

--- 41 unchanged lines hidden ---
850 default:
851 error = EINVAL;
852 break;
853 }
854 return (error);
855}
856
857static struct cdevsw crypto_cdevsw = {

--- 41 unchanged lines hidden ---