This source file includes following definitions.
- cryptof_read
- cryptof_write
- cryptof_ioctl
- cryptodev_op
- cryptodev_cb
- cryptodevkey_cb
- cryptodev_key
- cryptof_poll
- cryptof_kqfilter
- cryptof_stat
- cryptof_close
- cryptoattach
- cryptoopen
- cryptoclose
- cryptoread
- cryptowrite
- cryptoioctl
- cryptopoll
- csefind
- csedelete
- cseadd
- csecreate
- csefree
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/malloc.h>
36 #include <sys/mbuf.h>
37 #include <sys/sysctl.h>
38 #include <sys/file.h>
39 #include <sys/filedesc.h>
40 #include <sys/errno.h>
41 #include <dev/rndvar.h>
42 #include <sys/conf.h>
43 #include <sys/device.h>
44 #include <crypto/md5.h>
45 #include <crypto/sha1.h>
46 #include <crypto/rmd160.h>
47 #include <crypto/cast.h>
48 #include <crypto/skipjack.h>
49 #include <crypto/blf.h>
50 #include <crypto/cryptodev.h>
51 #include <crypto/xform.h>
52
53 extern struct cryptocap *crypto_drivers;
54 extern int crypto_drivers_num;
55
56 struct csession {
57 TAILQ_ENTRY(csession) next;
58 u_int64_t sid;
59 u_int32_t ses;
60
61 u_int32_t cipher;
62 struct enc_xform *txform;
63 u_int32_t mac;
64 struct auth_hash *thash;
65
66 caddr_t key;
67 int keylen;
68 u_char tmp_iv[EALG_MAX_BLOCK_LEN];
69
70 caddr_t mackey;
71 int mackeylen;
72 u_char tmp_mac[CRYPTO_MAX_MAC_LEN];
73
74 struct iovec iovec[IOV_MAX];
75 struct uio uio;
76 int error;
77 };
78
79 struct fcrypt {
80 TAILQ_HEAD(csessionlist, csession) csessions;
81 int sesn;
82 };
83
84 void cryptoattach(int);
85
86 int cryptof_read(struct file *, off_t *, struct uio *, struct ucred *);
87 int cryptof_write(struct file *, off_t *, struct uio *, struct ucred *);
88 int cryptof_ioctl(struct file *, u_long, caddr_t, struct proc *p);
89 int cryptof_poll(struct file *, int, struct proc *);
90 int cryptof_kqfilter(struct file *, struct knote *);
91 int cryptof_stat(struct file *, struct stat *, struct proc *);
92 int cryptof_close(struct file *, struct proc *);
93
94 static struct fileops cryptofops = {
95 cryptof_read,
96 cryptof_write,
97 cryptof_ioctl,
98 cryptof_poll,
99 cryptof_kqfilter,
100 cryptof_stat,
101 cryptof_close
102 };
103
104 struct csession *csefind(struct fcrypt *, u_int);
105 int csedelete(struct fcrypt *, struct csession *);
106 struct csession *cseadd(struct fcrypt *, struct csession *);
107 struct csession *csecreate(struct fcrypt *, u_int64_t, caddr_t, u_int64_t,
108 caddr_t, u_int64_t, u_int32_t, u_int32_t, struct enc_xform *,
109 struct auth_hash *);
110 int csefree(struct csession *);
111
112 int cryptodev_op(struct csession *, struct crypt_op *, struct proc *);
113 int cryptodev_key(struct crypt_kop *);
114 int cryptodev_dokey(struct crypt_kop *kop, struct crparam kvp[]);
115
116 int cryptodev_cb(struct cryptop *);
117 int cryptodevkey_cb(struct cryptkop *);
118
119 int usercrypto = 1;
120 int userasymcrypto = 1;
121 int cryptodevallowsoft = 0;
122
123
124 int
125 cryptof_read(struct file *fp, off_t *poff, struct uio *uio, struct ucred *cred)
126 {
127 return (EIO);
128 }
129
130
131 int
132 cryptof_write(struct file *fp, off_t *poff, struct uio *uio, struct ucred *cred)
133 {
134 return (EIO);
135 }
136
137
138 int
139 cryptof_ioctl(struct file *fp, u_long cmd, caddr_t data, struct proc *p)
140 {
141 struct cryptoini cria, crie;
142 struct fcrypt *fcr = fp->f_data;
143 struct csession *cse;
144 struct session_op *sop;
145 struct crypt_op *cop;
146 struct enc_xform *txform = NULL;
147 struct auth_hash *thash = NULL;
148 u_int64_t sid;
149 u_int32_t ses;
150 int error = 0;
151
152 switch (cmd) {
153 case CIOCGSESSION:
154 sop = (struct session_op *)data;
155 switch (sop->cipher) {
156 case 0:
157 break;
158 case CRYPTO_DES_CBC:
159 txform = &enc_xform_des;
160 break;
161 case CRYPTO_3DES_CBC:
162 txform = &enc_xform_3des;
163 break;
164 case CRYPTO_BLF_CBC:
165 txform = &enc_xform_blf;
166 break;
167 case CRYPTO_CAST_CBC:
168 txform = &enc_xform_cast5;
169 break;
170 case CRYPTO_SKIPJACK_CBC:
171 txform = &enc_xform_skipjack;
172 break;
173 case CRYPTO_AES_CBC:
174 txform = &enc_xform_rijndael128;
175 break;
176 case CRYPTO_AES_CTR:
177 txform = &enc_xform_aes_ctr;
178 break;
179 case CRYPTO_ARC4:
180 txform = &enc_xform_arc4;
181 break;
182 case CRYPTO_NULL:
183 txform = &enc_xform_null;
184 break;
185 default:
186 return (EINVAL);
187 }
188
189 switch (sop->mac) {
190 case 0:
191 break;
192 #if 0
193 case CRYPTO_MD5_HMAC:
194 thash = &auth_hash_hmac_md5_96;
195 break;
196 case CRYPTO_SHA1_HMAC:
197 thash = &auth_hash_hmac_sha1_96;
198 break;
199 case CRYPTO_RIPEMD160_HMAC:
200 thash = &auth_hash_hmac_ripemd_160_96;
201 break;
202 case CRYPTO_MD5:
203 thash = &auth_hash_md5;
204 break;
205 case CRYPTO_SHA1:
206 thash = &auth_hash_sha1;
207 break;
208 #endif
209 default:
210 return (EINVAL);
211 }
212
213 bzero(&crie, sizeof(crie));
214 bzero(&cria, sizeof(cria));
215
216 if (txform) {
217 crie.cri_alg = txform->type;
218 crie.cri_klen = sop->keylen * 8;
219 if (sop->keylen > txform->maxkey ||
220 sop->keylen < txform->minkey) {
221 error = EINVAL;
222 goto bail;
223 }
224
225 MALLOC(crie.cri_key, u_int8_t *,
226 crie.cri_klen / 8, M_XDATA, M_WAITOK);
227 if ((error = copyin(sop->key, crie.cri_key,
228 crie.cri_klen / 8)))
229 goto bail;
230 if (thash)
231 crie.cri_next = &cria;
232 }
233
234 if (thash) {
235 cria.cri_alg = thash->type;
236 cria.cri_klen = sop->mackeylen * 8;
237 if (sop->mackeylen != thash->keysize) {
238 error = EINVAL;
239 goto bail;
240 }
241
242 if (cria.cri_klen) {
243 MALLOC(cria.cri_key, u_int8_t *,
244 cria.cri_klen / 8, M_XDATA, M_WAITOK);
245 if ((error = copyin(sop->mackey, cria.cri_key,
246 cria.cri_klen / 8)))
247 goto bail;
248 }
249 }
250
251 error = crypto_newsession(&sid, (txform ? &crie : &cria),
252 !cryptodevallowsoft);
253
254 if (error)
255 goto bail;
256
257 cse = csecreate(fcr, sid, crie.cri_key, crie.cri_klen,
258 cria.cri_key, cria.cri_klen, sop->cipher, sop->mac, txform,
259 thash);
260
261 if (cse == NULL) {
262 crypto_freesession(sid);
263 error = EINVAL;
264 goto bail;
265 }
266 sop->ses = cse->ses;
267
268 bail:
269 if (error) {
270 if (crie.cri_key)
271 FREE(crie.cri_key, M_XDATA);
272 if (cria.cri_key)
273 FREE(cria.cri_key, M_XDATA);
274 }
275 break;
276 case CIOCFSESSION:
277 ses = *(u_int32_t *)data;
278 cse = csefind(fcr, ses);
279 if (cse == NULL)
280 return (EINVAL);
281 csedelete(fcr, cse);
282 error = csefree(cse);
283 break;
284 case CIOCCRYPT:
285 cop = (struct crypt_op *)data;
286 cse = csefind(fcr, cop->ses);
287 if (cse == NULL)
288 return (EINVAL);
289 error = cryptodev_op(cse, cop, p);
290 break;
291 case CIOCKEY:
292 error = cryptodev_key((struct crypt_kop *)data);
293 break;
294 case CIOCASYMFEAT:
295 error = crypto_getfeat((int *)data);
296 break;
297 default:
298 error = EINVAL;
299 }
300 return (error);
301 }
302
303 int
304 cryptodev_op(struct csession *cse, struct crypt_op *cop, struct proc *p)
305 {
306 struct cryptop *crp = NULL;
307 struct cryptodesc *crde = NULL, *crda = NULL;
308 int i, s, error;
309 u_int32_t hid;
310
311 if (cop->len > 64*1024-4)
312 return (E2BIG);
313
314 if (cse->txform) {
315 if (cop->len == 0 || (cop->len % cse->txform->blocksize) != 0)
316 return (EINVAL);
317 }
318
319 bzero(&cse->uio, sizeof(cse->uio));
320 cse->uio.uio_iovcnt = 1;
321 cse->uio.uio_resid = 0;
322 cse->uio.uio_segflg = UIO_SYSSPACE;
323 cse->uio.uio_rw = UIO_WRITE;
324 cse->uio.uio_procp = p;
325 cse->uio.uio_iov = cse->iovec;
326 bzero(&cse->iovec, sizeof(cse->iovec));
327 cse->uio.uio_iov[0].iov_len = cop->len;
328 cse->uio.uio_iov[0].iov_base = malloc(cop->len, M_XDATA, M_WAITOK);
329 for (i = 0; i < cse->uio.uio_iovcnt; i++)
330 cse->uio.uio_resid += cse->uio.uio_iov[0].iov_len;
331
332
333 crp = crypto_getreq((cse->txform != NULL) + (cse->thash != NULL));
334 if (crp == NULL) {
335 error = ENOMEM;
336 goto bail;
337 }
338
339 if (cse->thash) {
340 crda = crp->crp_desc;
341 if (cse->txform)
342 crde = crda->crd_next;
343 } else {
344 if (cse->txform)
345 crde = crp->crp_desc;
346 else {
347 error = EINVAL;
348 goto bail;
349 }
350 }
351
352 if ((error = copyin(cop->src, cse->uio.uio_iov[0].iov_base, cop->len)))
353 goto bail;
354
355 if (crda) {
356 crda->crd_skip = 0;
357 crda->crd_len = cop->len;
358 crda->crd_inject = 0;
359
360 crda->crd_alg = cse->mac;
361 crda->crd_key = cse->mackey;
362 crda->crd_klen = cse->mackeylen * 8;
363 }
364
365 if (crde) {
366 if (cop->op == COP_ENCRYPT)
367 crde->crd_flags |= CRD_F_ENCRYPT;
368 else
369 crde->crd_flags &= ~CRD_F_ENCRYPT;
370 crde->crd_len = cop->len;
371 crde->crd_inject = 0;
372
373 crde->crd_alg = cse->cipher;
374 crde->crd_key = cse->key;
375 crde->crd_klen = cse->keylen * 8;
376 }
377
378 crp->crp_ilen = cop->len;
379 crp->crp_buf = (caddr_t)&cse->uio;
380 crp->crp_callback = cryptodev_cb;
381 crp->crp_sid = cse->sid;
382 crp->crp_opaque = cse;
383
384 if (cop->iv) {
385 if (crde == NULL) {
386 error = EINVAL;
387 goto bail;
388 }
389 if (cse->cipher == CRYPTO_ARC4) {
390 error = EINVAL;
391 goto bail;
392 }
393 if ((error = copyin(cop->iv, cse->tmp_iv, cse->txform->blocksize)))
394 goto bail;
395 bcopy(cse->tmp_iv, crde->crd_iv, cse->txform->blocksize);
396 crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
397 crde->crd_skip = 0;
398 } else if (cse->cipher == CRYPTO_ARC4) {
399 crde->crd_skip = 0;
400 } else if (crde) {
401 crde->crd_flags |= CRD_F_IV_PRESENT;
402 crde->crd_skip = cse->txform->blocksize;
403 crde->crd_len -= cse->txform->blocksize;
404 }
405
406 if (cop->mac) {
407 if (crda == NULL) {
408 error = EINVAL;
409 goto bail;
410 }
411 crp->crp_mac = cse->tmp_mac;
412 }
413
414
415 crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_NOQUEUE;
416 hid = (crp->crp_sid >> 32) & 0xffffffff;
417 if (hid >= crypto_drivers_num)
418 goto dispatch;
419 if (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_SOFTWARE)
420 goto dispatch;
421 if (crypto_drivers[hid].cc_process == NULL)
422 goto dispatch;
423 error = crypto_drivers[hid].cc_process(crp);
424 if (error) {
425
426 crp->crp_etype = 0;
427 goto dispatch;
428 }
429 goto processed;
430 dispatch:
431 crp->crp_flags = CRYPTO_F_IOV;
432 crypto_dispatch(crp);
433 processed:
434 s = splnet();
435 while (!(crp->crp_flags & CRYPTO_F_DONE)) {
436 error = tsleep(cse, PSOCK, "crydev", 0);
437 }
438 splx(s);
439 if (error) {
440
441 goto bail;
442 }
443
444 if (cse->error) {
445 error = cse->error;
446 goto bail;
447 }
448 if (crp->crp_etype != 0) {
449 error = crp->crp_etype;
450 goto bail;
451 }
452
453
454 if (cop->dst &&
455 (error = copyout(cse->uio.uio_iov[0].iov_base, cop->dst, cop->len)))
456 goto bail;
457
458 if (cop->mac &&
459 (error = copyout(crp->crp_mac, cop->mac, cse->thash->authsize)))
460 goto bail;
461
462 bail:
463 if (crp)
464 crypto_freereq(crp);
465 if (cse->uio.uio_iov[0].iov_base)
466 free(cse->uio.uio_iov[0].iov_base, M_XDATA);
467
468 return (error);
469 }
470
471 int
472 cryptodev_cb(struct cryptop *crp)
473 {
474 struct csession *cse = crp->crp_opaque;
475
476 cse->error = crp->crp_etype;
477 if (crp->crp_etype == EAGAIN) {
478 crp->crp_flags = CRYPTO_F_IOV;
479 return crypto_dispatch(crp);
480 }
481 wakeup(cse);
482 return (0);
483 }
484
485 int
486 cryptodevkey_cb(struct cryptkop *krp)
487 {
488
489 wakeup(krp);
490 return (0);
491 }
492
493 int
494 cryptodev_key(struct crypt_kop *kop)
495 {
496 struct cryptkop *krp = NULL;
497 int error = EINVAL;
498 int in, out, size, i;
499
500 if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) {
501 return (EFBIG);
502 }
503
504 in = kop->crk_iparams;
505 out = kop->crk_oparams;
506 switch (kop->crk_op) {
507 case CRK_MOD_EXP:
508 if (in == 3 && out == 1)
509 break;
510 return (EINVAL);
511 case CRK_MOD_EXP_CRT:
512 if (in == 6 && out == 1)
513 break;
514 return (EINVAL);
515 case CRK_DSA_SIGN:
516 if (in == 5 && out == 2)
517 break;
518 return (EINVAL);
519 case CRK_DSA_VERIFY:
520 if (in == 7 && out == 0)
521 break;
522 return (EINVAL);
523 case CRK_DH_COMPUTE_KEY:
524 if (in == 3 && out == 1)
525 break;
526 return (EINVAL);
527 default:
528 return (EINVAL);
529 }
530
531 krp = malloc(sizeof *krp, M_XDATA, M_WAITOK);
532 bzero(krp, sizeof *krp);
533 krp->krp_op = kop->crk_op;
534 krp->krp_status = kop->crk_status;
535 krp->krp_iparams = kop->crk_iparams;
536 krp->krp_oparams = kop->crk_oparams;
537 krp->krp_status = 0;
538 krp->krp_callback = cryptodevkey_cb;
539
540 for (i = 0; i < CRK_MAXPARAM; i++) {
541 krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits;
542 if (kop->crk_param[i].crp_nbits > 65536) {
543
544 goto fail;
545 }
546 }
547 for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) {
548 size = (krp->krp_param[i].crp_nbits + 7) / 8;
549 if (size == 0)
550 continue;
551 krp->krp_param[i].crp_p = malloc(size, M_XDATA, M_WAITOK);
552 if (i >= krp->krp_iparams)
553 continue;
554 error = copyin(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p, size);
555 if (error)
556 goto fail;
557 }
558
559 error = crypto_kdispatch(krp);
560 if (error)
561 goto fail;
562 error = tsleep(krp, PSOCK, "crydev", 0);
563 if (error) {
564
565 goto fail;
566 }
567
568 if (krp->krp_status != 0) {
569 error = krp->krp_status;
570 goto fail;
571 }
572
573 for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) {
574 size = (krp->krp_param[i].crp_nbits + 7) / 8;
575 if (size == 0)
576 continue;
577 error = copyout(krp->krp_param[i].crp_p, kop->crk_param[i].crp_p, size);
578 if (error)
579 goto fail;
580 }
581
582 fail:
583 if (krp) {
584 kop->crk_status = krp->krp_status;
585 for (i = 0; i < CRK_MAXPARAM; i++) {
586 if (krp->krp_param[i].crp_p)
587 free(krp->krp_param[i].crp_p, M_XDATA);
588 }
589 free(krp, M_XDATA);
590 }
591 return (error);
592 }
593
594
595 int
596 cryptof_poll(struct file *fp, int events, struct proc *p)
597 {
598 return (0);
599 }
600
601
602 int
603 cryptof_kqfilter(struct file *fp, struct knote *kn)
604 {
605 return (0);
606 }
607
608
609 int
610 cryptof_stat(struct file *fp, struct stat *sb, struct proc *p)
611 {
612 return (EOPNOTSUPP);
613 }
614
615
616 int
617 cryptof_close(struct file *fp, struct proc *p)
618 {
619 struct fcrypt *fcr = fp->f_data;
620 struct csession *cse;
621
622 while ((cse = TAILQ_FIRST(&fcr->csessions))) {
623 TAILQ_REMOVE(&fcr->csessions, cse, next);
624 (void)csefree(cse);
625 }
626 FREE(fcr, M_XDATA);
627 fp->f_data = NULL;
628 return 0;
629 }
630
631 void
632 cryptoattach(int n)
633 {
634 }
635
636 int
637 cryptoopen(dev_t dev, int flag, int mode, struct proc *p)
638 {
639 if (usercrypto == 0)
640 return (ENXIO);
641 #ifdef CRYPTO
642 return (0);
643 #else
644 return (ENXIO);
645 #endif
646 }
647
648 int
649 cryptoclose(dev_t dev, int flag, int mode, struct proc *p)
650 {
651 return (0);
652 }
653
654 int
655 cryptoread(dev_t dev, struct uio *uio, int ioflag)
656 {
657 return (EIO);
658 }
659
660 int
661 cryptowrite(dev_t dev, struct uio *uio, int ioflag)
662 {
663 return (EIO);
664 }
665
666 int
667 cryptoioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
668 {
669 struct file *f;
670 struct fcrypt *fcr;
671 int fd, error;
672
673 switch (cmd) {
674 case CRIOGET:
675 MALLOC(fcr, struct fcrypt *,
676 sizeof(struct fcrypt), M_XDATA, M_WAITOK);
677 TAILQ_INIT(&fcr->csessions);
678 fcr->sesn = 0;
679
680 error = falloc(p, &f, &fd);
681 if (error) {
682 FREE(fcr, M_XDATA);
683 return (error);
684 }
685 f->f_flag = FREAD | FWRITE;
686 f->f_type = DTYPE_CRYPTO;
687 f->f_ops = &cryptofops;
688 f->f_data = fcr;
689 *(u_int32_t *)data = fd;
690 FILE_SET_MATURE(f);
691 break;
692 default:
693 error = EINVAL;
694 break;
695 }
696 return (error);
697 }
698
699 int
700 cryptopoll(dev_t dev, int events, struct proc *p)
701 {
702 return (seltrue(dev, events, p));
703 }
704
705 struct csession *
706 csefind(struct fcrypt *fcr, u_int ses)
707 {
708 struct csession *cse;
709
710 TAILQ_FOREACH(cse, &fcr->csessions, next)
711 if (cse->ses == ses)
712 return (cse);
713 return (NULL);
714 }
715
716 int
717 csedelete(struct fcrypt *fcr, struct csession *cse_del)
718 {
719 struct csession *cse;
720
721 TAILQ_FOREACH(cse, &fcr->csessions, next) {
722 if (cse == cse_del) {
723 TAILQ_REMOVE(&fcr->csessions, cse, next);
724 return (1);
725 }
726 }
727 return (0);
728 }
729
730 struct csession *
731 cseadd(struct fcrypt *fcr, struct csession *cse)
732 {
733 TAILQ_INSERT_TAIL(&fcr->csessions, cse, next);
734 cse->ses = fcr->sesn++;
735 return (cse);
736 }
737
738 struct csession *
739 csecreate(struct fcrypt *fcr, u_int64_t sid, caddr_t key, u_int64_t keylen,
740 caddr_t mackey, u_int64_t mackeylen, u_int32_t cipher, u_int32_t mac,
741 struct enc_xform *txform, struct auth_hash *thash)
742 {
743 struct csession *cse;
744
745 MALLOC(cse, struct csession *, sizeof(struct csession),
746 M_XDATA, M_NOWAIT);
747 if (cse == NULL)
748 return NULL;
749 cse->key = key;
750 cse->keylen = keylen/8;
751 cse->mackey = mackey;
752 cse->mackeylen = mackeylen/8;
753 cse->sid = sid;
754 cse->cipher = cipher;
755 cse->mac = mac;
756 cse->txform = txform;
757 cse->thash = thash;
758 cseadd(fcr, cse);
759 return (cse);
760 }
761
762 int
763 csefree(struct csession *cse)
764 {
765 int error;
766
767 error = crypto_freesession(cse->sid);
768 if (cse->key)
769 FREE(cse->key, M_XDATA);
770 if (cse->mackey)
771 FREE(cse->mackey, M_XDATA);
772 FREE(cse, M_XDATA);
773 return (error);
774 }