Annotation of sys/crypto/cryptodev.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: cryptodev.c,v 1.66 2006/10/25 15:10:25 tedu Exp $ */
2:
3: /*
4: * Copyright (c) 2001 Theo de Raadt
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
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: *
16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26: *
27: * Effort sponsored in part by the Defense Advanced Research Projects
28: * Agency (DARPA) and Air Force Research Laboratory, Air Force
29: * Materiel Command, USAF, under agreement number F30602-01-2-0537.
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; /* userland may do crypto requests */
120: int userasymcrypto = 1; /* userland may do asymmetric crypto reqs */
121: int cryptodevallowsoft = 0; /* only use hardware crypto */
122:
123: /* ARGSUSED */
124: int
125: cryptof_read(struct file *fp, off_t *poff, struct uio *uio, struct ucred *cred)
126: {
127: return (EIO);
128: }
129:
130: /* ARGSUSED */
131: int
132: cryptof_write(struct file *fp, off_t *poff, struct uio *uio, struct ucred *cred)
133: {
134: return (EIO);
135: }
136:
137: /* ARGSUSED */
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: /* number of requests, not logical and */
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) { /* XXX use flag? */
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) { /* XXX use flag? */
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: /* try the fast path first */
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: /* clear error */
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: /* XXX can this happen? if so, how do we recover? */
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: /* XXX how big do we need to support? */
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: /* XXX can this happen? if so, how do we recover? */
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: /* ARGSUSED */
595: int
596: cryptof_poll(struct file *fp, int events, struct proc *p)
597: {
598: return (0);
599: }
600:
601: /* ARGSUSED */
602: int
603: cryptof_kqfilter(struct file *fp, struct knote *kn)
604: {
605: return (0);
606: }
607:
608: /* ARGSUSED */
609: int
610: cryptof_stat(struct file *fp, struct stat *sb, struct proc *p)
611: {
612: return (EOPNOTSUPP);
613: }
614:
615: /* ARGSUSED */
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: }
CVSweb