summaryrefslogtreecommitdiff
path: root/sys/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'sys/crypto')
-rw-r--r--sys/crypto/criov.c173
-rw-r--r--sys/crypto/crypto.c13
-rw-r--r--sys/crypto/crypto.h23
-rw-r--r--sys/crypto/cryptodev.c530
-rw-r--r--sys/crypto/cryptodev.h35
-rw-r--r--sys/crypto/cryptosoft.c4
6 files changed, 769 insertions, 9 deletions
diff --git a/sys/crypto/criov.c b/sys/crypto/criov.c
new file mode 100644
index 00000000000..3c3ce6f224c
--- /dev/null
+++ b/sys/crypto/criov.c
@@ -0,0 +1,173 @@
+/* $OpenBSD: criov.c,v 1.1 2001/05/13 15:39:26 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1999 Theo de Raadt
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/errno.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/pmap.h>
+
+#include <crypto/crypto.h>
+
+int
+iov2pages(crio, np, pp, lp, maxp, nicep)
+ struct criov *crio;
+ int *np;
+ long *pp;
+ int *lp;
+ int maxp;
+ int *nicep;
+{
+ int npa = 0, tlen = 0;
+ int i;
+
+ for (i = 0; i < crio->niov; i++) {
+ vaddr_t va, off;
+ paddr_t pa;
+ int len;
+
+ if ((len = crio->iov[i].iov_len) == 0)
+ continue;
+ tlen += len;
+ va = (vaddr_t)crio->iov[i].iov_base;
+ off = va & PAGE_MASK;
+ va -= off;
+
+next_page:
+ pa = pmap_extract(pmap_kernel(), va);
+ if (pa == 0)
+ panic("mbuf2pages: pa == 0");
+
+ pa += off;
+
+ lp[npa] = len;
+ pp[npa] = pa;
+
+ if (++npa > maxp)
+ return (0);
+
+ if (len + off > PAGE_SIZE) {
+ lp[npa - 1] = PAGE_SIZE - off;
+ va += PAGE_SIZE;
+ len -= PAGE_SIZE;
+ goto next_page;
+ }
+ }
+
+ if (nicep) {
+ int nice = 1;
+ int i;
+
+ /* see if each [pa,len] entry is long-word aligned */
+ for (i = 0; i < npa; i++)
+ if ((lp[i] & 3) || (pp[i] & 3))
+ nice = 0;
+ *nicep = nice;
+ }
+
+ *np = npa;
+ return (tlen);
+}
+
+void
+criov_copydata(crio, off, len, cp)
+ struct criov *crio;
+ int off, len;
+ caddr_t cp;
+{
+ struct iovec *iov = crio->iov;
+ int iol = crio->niov;
+ unsigned count;
+
+ if (off < 0)
+ panic("criov_copydata: off %d < 0", off);
+ if (len < 0)
+ panic("criov_copydata: len %d < 0", len);
+ while (off > 0) {
+ if (iol == 0)
+ panic("iov_copydata: empty in skip");
+ if (off < iov->iov_len)
+ break;
+ off -= iov->iov_len;
+ iol--;
+ iov++;
+ }
+ while (len > 0) {
+ if (iol == 0)
+ panic("criov_copydata: empty");
+ count = min(iov->iov_len - off, len);
+ bcopy(((caddr_t)iov->iov_base) + off, cp, count);
+ len -= count;
+ cp += count;
+ off = 0;
+ iol--;
+ iov++;
+ }
+}
+
+void
+criov_copyback(crio, off, len, cp)
+ struct criov *crio;
+ int off, len;
+ caddr_t cp;
+{
+ struct iovec *iov = crio->iov;
+ int iol = crio->niov;
+ unsigned count;
+
+ if (off < 0)
+ panic("criov_copyback: off %d < 0", off);
+ if (len < 0)
+ panic("criov_copyback: len %d < 0", len);
+ while (off > 0) {
+ if (iol == 0)
+ panic("criov_copyback: empty in skip");
+ if (off < iov->iov_len)
+ break;
+ off -= iov->iov_len;
+ iol--;
+ iov++;
+ }
+ while (len > 0) {
+ if (iol == 0)
+ panic("criov_copyback: empty");
+ count = min(iov->iov_len - off, len);
+ bcopy(cp, ((caddr_t)iov->iov_base) + off, count);
+ len -= count;
+ cp += count;
+ off = 0;
+ iol--;
+ iov++;
+ }
+}
diff --git a/sys/crypto/crypto.c b/sys/crypto/crypto.c
index 256eeb88db1..4ca2f90759d 100644
--- a/sys/crypto/crypto.c
+++ b/sys/crypto/crypto.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: crypto.c,v 1.16 2001/05/05 00:31:34 angelos Exp $ */
+/* $OpenBSD: crypto.c,v 1.17 2001/05/13 15:39:26 deraadt Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
@@ -53,7 +53,7 @@ struct cryptop **crp_req_queue_tail = NULL;
* Create a new session.
*/
int
-crypto_newsession(u_int64_t *sid, struct cryptoini *cri)
+crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard)
{
struct cryptoini *cr;
u_int32_t hid, lid;
@@ -80,6 +80,11 @@ crypto_newsession(u_int64_t *sid, struct cryptoini *cri)
(crypto_drivers[hid].cc_flags & CRYPTOCAP_F_CLEANUP))
continue;
+ /* hardware requested -- ignore software drivers */
+ if (hard &&
+ (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_SOFTWARE))
+ continue;
+
/* See if all the algorithms are supported */
for (cr = cri; cr; cr = cr->cri_next)
if (crypto_drivers[hid].cc_alg[cr->cri_alg] == 0)
@@ -325,7 +330,7 @@ crypto_invoke(struct cryptop *crp)
for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next)
crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI);
- if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI)) == 0)
+ if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI), 0) == 0)
crp->crp_sid = nid;
crp->crp_etype = EAGAIN;
@@ -342,7 +347,7 @@ crypto_invoke(struct cryptop *crp)
for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next)
crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI);
- if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI)) == 0)
+ if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI), 0) == 0)
crp->crp_sid = nid;
crp->crp_etype = EAGAIN;
diff --git a/sys/crypto/crypto.h b/sys/crypto/crypto.h
index b37026f3f9a..bcc5e56f563 100644
--- a/sys/crypto/crypto.h
+++ b/sys/crypto/crypto.h
@@ -70,6 +70,7 @@ struct cryptoini
int cri_rnd; /* Algorithm rounds, where relevant */
caddr_t cri_key; /* key to use */
u_int8_t cri_iv[EALG_MAX_BLOCK_LEN]; /* IV to use */
+ int cri_insert; /* XXX Number of bytes MAC "uses" */
struct cryptoini *cri_next;
};
@@ -115,7 +116,9 @@ struct cryptop
*/
int crp_flags;
-#define CRYPTO_F_IMBUF 0x0001 /* Input is an mbuf chain, otherwise contig */
+#define CRYPTO_F_IMBUF 0x0001 /* Input/output are mbuf chains, otherwise contig */
+#define CRYPTO_F_IOV 0x0002 /* Input/output are uio */
+#define CRYPTO_F_REL 0x0004 /* Must return data in same place */
caddr_t crp_buf; /* Data to be processed */
@@ -126,6 +129,11 @@ struct cryptop
int (*crp_callback) (struct cryptop *); /* Callback function */
struct cryptop *crp_next;
+
+ caddr_t crp_iv;
+ caddr_t crp_mac;
+ int crp_mac_trunc_len;
+
};
#define CRYPTO_BUF_CONTIG 0x1
@@ -142,6 +150,7 @@ struct cryptocap
u_int8_t cc_alg[CRYPTO_ALGORITHM_MAX + 1]; /* Supported */
u_int8_t cc_flags;
#define CRYPTOCAP_F_CLEANUP 0x1
+#define CRYPTOCAP_F_SOFTWARE 0x02
int (*cc_newsession) (u_int32_t *, struct cryptoini *);
int (*cc_process) (struct cryptop *);
@@ -149,8 +158,13 @@ struct cryptocap
};
+struct criov {
+ int niov;
+ struct iovec iov[IOV_MAX];
+};
+
#ifdef _KERNEL
-extern int crypto_newsession(u_int64_t *, struct cryptoini *);
+extern int crypto_newsession(u_int64_t *, struct cryptoini *, int);
extern int crypto_freesession(u_int64_t);
extern int crypto_dispatch(struct cryptop *);
extern int crypto_register(u_int32_t, int,
@@ -163,7 +177,10 @@ extern int crypto_invoke(struct cryptop *);
extern void crypto_done(struct cryptop *);
struct mbuf;
-int mbuf2pages(struct mbuf *, int *, long *, int *, int, int *);
+int mbuf2pages __P((struct mbuf *, int *, long *, int *, int, int *));
+int iov2pages __P((struct criov *, int *, long *, int *, int, int *));
+void criov_copydata __P((struct criov *, int, int, caddr_t));
+void criov_copyback __P((struct criov *, int, int, caddr_t));
extern struct cryptop *crypto_getreq(int);
extern void crypto_freereq(struct cryptop *);
diff --git a/sys/crypto/cryptodev.c b/sys/crypto/cryptodev.c
new file mode 100644
index 00000000000..96c80c5eae4
--- /dev/null
+++ b/sys/crypto/cryptodev.c
@@ -0,0 +1,530 @@
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/sysctl.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
+#include <sys/errno.h>
+#include <sys/md5k.h>
+#include <dev/rndvar.h>
+#include <sys/conf.h>
+#include <sys/device.h>
+#include <crypto/sha1.h>
+#include <crypto/rmd160.h>
+#include <crypto/cast.h>
+#include <crypto/skipjack.h>
+#include <crypto/blf.h>
+#include <crypto/crypto.h>
+#include <crypto/xform.h>
+#include <crypto/cryptodev.h>
+
+struct csession {
+ TAILQ_ENTRY(csession) next;
+ u_int64_t sid;
+ u_int32_t ses;
+
+ u_int32_t cipher;
+ caddr_t key;
+ int keylen;
+ u_char tmp_iv[16]; /* XXX MAX_IV_SIZE */
+
+ u_int32_t mac;
+ caddr_t mackey;
+ int mackeylen;
+ u_char tmp_mac[16]; /* XXX MAX_MAC_SIZE */
+
+ struct criov criov;
+ int error;
+};
+
+struct fcrypt {
+ TAILQ_HEAD(csessionlist, csession) csessions;
+ int sesn;
+};
+
+void cryptoattach __P((int));
+
+int cryptoopen __P((dev_t, int, int, struct proc *));
+int cryptoclose __P((dev_t, int, int, struct proc *));
+int cryptoread __P((dev_t, struct uio *, int));
+int cryptowrite __P((dev_t, struct uio *, int));
+int cryptoioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
+int cryptoselect __P((dev_t, int, struct proc *));
+
+int cryptof_read(struct file *, off_t *, struct uio *, struct ucred *);
+int cryptof_write(struct file *, off_t *, struct uio *, struct ucred *);
+int cryptof_ioctl(struct file *, u_long, caddr_t, struct proc *p);
+int cryptof_select(struct file *, int, struct proc *);
+int cryptof_kqfilter(struct file *, struct knote *);
+int cryptof_close(struct file *, struct proc *);
+
+static struct fileops cryptofops = {
+ cryptof_read, cryptof_write, cryptof_ioctl,
+ cryptof_select, cryptof_kqfilter, cryptof_close };
+
+struct csession *csefind(struct fcrypt *, u_int);
+int csedelete(struct fcrypt *, struct csession *);
+struct csession *cseadd(struct fcrypt *, struct csession *);
+struct csession *csecreate(struct fcrypt *, u_int64_t, caddr_t, caddr_t);
+void csefree(struct csession *);
+
+int crypto_op(struct csession *, struct crypt_op *);
+
+/* ARGSUSED */
+int
+cryptof_read(fp, poff, uio, cred)
+ struct file *fp;
+ off_t *poff;
+ struct uio *uio;
+ struct ucred *cred;
+{
+ return (EIO);
+}
+
+/* ARGSUSED */
+int
+cryptof_write(fp, poff, uio, cred)
+ struct file *fp;
+ off_t *poff;
+ struct uio *uio;
+ struct ucred *cred;
+{
+ return (EIO);
+}
+
+/* ARGSUSED */
+int
+cryptof_ioctl(fp, cmd, data, p)
+ struct file *fp;
+ u_long cmd;
+ caddr_t data;
+ struct proc *p;
+{
+ struct cryptoini cria, crie;
+ struct fcrypt *fcr = (struct fcrypt *)fp->f_data;
+ struct csession *cse;
+ struct session_op *sop;
+ struct crypt_op *cop;
+ struct enc_xform *txform = NULL;
+ struct auth_hash *thash = NULL;
+ u_int64_t sid;
+ u_int32_t ses;
+ int error = 0;
+
+ switch (cmd) {
+ case CIOCGSESSION:
+ sop = (struct session_op *)data;
+ switch (sop->cipher) {
+ case 0:
+ break;
+ case CRYPTO_DES_CBC:
+ txform = &enc_xform_des;
+ break;
+ case CRYPTO_3DES_CBC:
+ txform = &enc_xform_3des;
+ break;
+ case CRYPTO_BLF_CBC:
+ txform = &enc_xform_blf;
+ break;
+ case CRYPTO_CAST_CBC:
+ txform = &enc_xform_cast5;
+ break;
+ case CRYPTO_SKIPJACK_CBC:
+ txform = &enc_xform_skipjack;
+ break;
+ case CRYPTO_AES_CBC:
+ txform = &enc_xform_rijndael128;
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ switch (sop->mac) {
+ case 0:
+ break;
+ case CRYPTO_MD5_HMAC:
+ thash = &auth_hash_hmac_md5_96;
+ break;
+ case CRYPTO_SHA1_HMAC:
+ thash = &auth_hash_hmac_sha1_96;
+ break;
+ case CRYPTO_RIPEMD160_HMAC:
+ thash = &auth_hash_hmac_ripemd_160_96;
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ bzero(&crie, sizeof(crie));
+ bzero(&cria, sizeof(cria));
+
+ if (txform) {
+ crie.cri_alg = txform->type;
+ crie.cri_klen = sop->keylen * 8; /* XXX range check */
+
+ MALLOC(crie.cri_key, u_int8_t *,
+ crie.cri_klen / 8, M_XDATA, M_WAITOK);
+ if ((error = copyin(sop->key, crie.cri_key,
+ crie.cri_klen / 8)))
+ goto bail;
+ if (thash)
+ crie.cri_next = &cria;
+ }
+
+ if (thash) {
+ cria.cri_alg = thash->type;
+ cria.cri_klen = sop->mackeylen * 8; /* XXX range check */
+
+ MALLOC(cria.cri_key, u_int8_t *,
+ cria.cri_klen / 8, M_XDATA, M_WAITOK);
+ if ((error = copyin(sop->mackey, cria.cri_key,
+ cria.cri_klen / 8)))
+ goto bail;
+ }
+
+ error = crypto_newsession(&sid, (txform ? &crie : &cria), 1);
+
+bail:
+ if (error) {
+ if (crie.cri_key)
+ FREE(crie.cri_key, M_XDATA);
+ if (cria.cri_key)
+ FREE(cria.cri_key, M_XDATA);
+ return (error);
+ }
+
+ cse = csecreate(fcr, sid, crie.cri_key, cria.cri_key);
+ sop->ses = cse->ses;
+ break;
+ case CIOCFSESSION:
+ ses = *(u_int32_t *)data;
+ cse = csefind(fcr, ses);
+ if (cse == NULL)
+ return (EINVAL);
+ error = crypto_freesession(cse->sid);
+ csedelete(fcr, cse);
+ csefree(cse);
+ break;
+ case CIOCCRYPT:
+ cse = csefind(fcr, cop->ses);
+ if (cse == NULL)
+ return (EINVAL);
+ error = crypto_op(cse, cop);
+ break;
+ default:
+ error = EINVAL;
+ }
+ return (error);
+}
+
+int cryptodev_cb(void *);
+
+
+int
+crypto_op(struct csession *cse, struct crypt_op *cop)
+{
+ struct cryptop *crp = NULL;
+ struct cryptodesc *crde = NULL, *crda = NULL;
+ int error;
+
+ if (cop->len > 64*1024)
+ return (E2BIG);
+
+ bzero(&cse->criov, sizeof(cse->criov));
+ cse->criov.niov = 1;
+ cse->criov.iov[0].iov_len = cop->len;
+ cse->criov.iov[0].iov_base = malloc(cop->len, M_XDATA, M_WAITOK);
+ if (cse->criov.iov[0].iov_base == NULL)
+ return (ENOMEM);
+
+ crp = crypto_getreq((cse->cipher > 0) + (cse->mac > 0));
+ if (crp == NULL)
+ goto bail;
+
+ if (cse->mac) {
+ crda = crp->crp_desc;
+ if (cse->cipher)
+ crde = crda->crd_next;
+ } else {
+ if (cse->cipher)
+ crde = crp->crp_desc;
+ else {
+ error = EINVAL;
+ goto bail;
+ }
+ }
+
+ if ((error = copyin(cop->src, cse->criov.iov[0].iov_base, cop->len)))
+ goto bail;
+
+ if (crda) {
+ crda->crd_skip = 0;
+ crda->crd_len = cop->len;
+ crda->crd_inject = 0; /* ??? */
+
+ crda->crd_alg = cse->mac;
+ crda->crd_key = cse->mackey;
+ crda->crd_klen = cse->mackeylen * 8;
+ }
+
+ if (crde) {
+ crde->crd_skip = 0;
+ crde->crd_len = cop->len;
+ crde->crd_inject = 0; /* ??? */
+
+ crde->crd_alg = cse->cipher;
+ crde->crd_key = cse->key;
+ crde->crd_klen = cse->keylen * 8;
+ }
+
+ crp->crp_ilen = cop->len;
+ crp->crp_flags = CRYPTO_F_IOV;
+ crp->crp_buf = (caddr_t)&cse->criov;
+ crp->crp_callback = (int (*) (struct cryptop *)) cryptodev_cb;
+ crp->crp_sid = cse->sid;
+ crp->crp_opaque = (void *)cse;
+
+ if (cop->iv) {
+ if (crde == NULL) {
+ error = EINVAL;
+ goto bail;
+ }
+ if ((error = copyin(cop->iv, cse->tmp_iv, 8))) /* XXX sop->iv_size? */
+ goto bail;
+ }
+
+ if (cop->mac) {
+ if (crda == NULL) {
+ error = EINVAL;
+ goto bail;
+ }
+ if ((error = copyin(cop->mac, cse->tmp_mac, 16))) /* XXX */
+ goto bail;
+ crp->crp_mac_trunc_len = 16; /* XXX */
+ }
+
+ crypto_dispatch(crp);
+ error = tsleep(cse, PSOCK, "crydev", 0);
+ if (error) {
+ /// XXX can this happen? if so, how do we recover?
+ return (error);
+ }
+
+ if (cse->error)
+ goto bail;
+
+ if ((error = copyout(cse->criov.iov[0].iov_base, cop->dst, cop->len)))
+ goto bail;
+
+ if (cop->mac &&
+ (error = copyout(crp->crp_mac, cop->mac, crp->crp_mac_trunc_len)))
+ goto bail;
+
+bail:
+ if (crp)
+ crypto_freereq(crp);
+ if (cse->criov.iov[0].iov_base)
+ free(cse->criov.iov[0].iov_base, M_XDATA);
+
+ return (error);
+}
+
+int
+cryptodev_cb(void *op)
+{
+ struct cryptop *crp = (struct cryptop *) op;
+ struct csession *cse = (struct csession *)crp->crp_opaque;
+
+ cse->error = crp->crp_etype;
+ if (crp->crp_etype == EAGAIN)
+ return crypto_dispatch(crp);
+ wakeup(cse);
+ return (0);
+}
+
+
+
+/* ARGSUSED */
+int
+cryptof_select(fp, which, p)
+ struct file *fp;
+ int which;
+ struct proc *p;
+{
+ return (0);
+}
+
+/* ARGSUSED */
+int
+cryptof_kqfilter(fp, kn)
+ struct file *fp;
+ struct knote *kn;
+{
+ return (0);
+}
+
+/* ARGSUSED */
+int
+cryptof_close(fp, p)
+ struct file *fp;
+ struct proc *p;
+{
+ struct fcrypt *fcr = (struct fcrypt *)fp->f_data;
+ struct csession *cse;
+
+ while ((cse = TAILQ_FIRST(&fcr->csessions))) {
+ TAILQ_REMOVE(&fcr->csessions, cse, next);
+ csefree(cse);
+ }
+ FREE(fcr, M_XDATA);
+ fp->f_data = NULL;
+ return 0;
+}
+
+void
+cryptoattach(int n)
+{
+}
+
+int
+cryptoopen(dev, flag, mode, p)
+ dev_t dev;
+ int flag;
+ int mode;
+ struct proc *p;
+{
+ return (0);
+}
+
+int
+cryptoclose(dev, flag, mode, p)
+ dev_t dev;
+ int flag;
+ int mode;
+ struct proc *p;
+{
+ return (0);
+}
+
+int
+cryptoread(dev, uio, ioflag)
+ dev_t dev;
+ struct uio *uio;
+ int ioflag;
+{
+ return (EIO);
+}
+
+int
+cryptowrite(dev, uio, ioflag)
+ dev_t dev;
+ struct uio *uio;
+ int ioflag;
+{
+ return (EIO);
+}
+
+int
+cryptoioctl(dev, cmd, data, flag, p)
+ dev_t dev;
+ u_long cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+ struct file *f;
+ struct fcrypt *fcr;
+ int fd, error;
+
+ switch (cmd) {
+ case CRIOGET:
+ MALLOC(fcr, struct fcrypt *,
+ sizeof(struct fcrypt), M_XDATA, M_WAITOK);
+ TAILQ_INIT(&fcr->csessions);
+
+ error = falloc(p, &f, &fd);
+
+ if (error) {
+ FREE(fcr, M_XDATA);
+ return (error);
+ }
+ f->f_flag = FREAD | FWRITE;
+ f->f_type = DTYPE_PIPE;
+ f->f_ops = &cryptofops;
+ f->f_data = (caddr_t)fcr;
+ *(u_int32_t *)data = fd;
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ return (error);
+}
+
+int
+cryptoselect(dev, rw, p)
+ dev_t dev;
+ int rw;
+ struct proc *p;
+{
+ return (0);
+}
+
+struct csession *
+csefind(struct fcrypt *fcr, u_int ses)
+{
+ struct csession *cse;
+
+ TAILQ_FOREACH(cse, &fcr->csessions, next)
+ if (cse->ses == ses)
+ return (cse);
+ return (NULL);
+}
+
+int
+csedelete(struct fcrypt *fcr, struct csession *cse_del)
+{
+ struct csession *cse;
+
+ TAILQ_FOREACH(cse, &fcr->csessions, next) {
+ if (cse == cse_del) {
+ TAILQ_REMOVE(&fcr->csessions, cse, next);
+ return (1);
+ }
+ }
+ return (0);
+}
+
+struct csession *
+cseadd(struct fcrypt *fcr, struct csession *cse)
+{
+ TAILQ_INSERT_TAIL(&fcr->csessions, cse, next);
+ cse->ses = fcr->sesn++;
+ return (cse);
+}
+
+struct csession *
+csecreate(struct fcrypt *fcr, u_int64_t sid, caddr_t key, caddr_t mackey)
+{
+ struct csession *cse;
+
+ MALLOC(cse, struct csession *, sizeof(struct csession),
+ M_XDATA, M_NOWAIT);
+ cse->key = key;
+ cse->mackey = mackey;
+ cse->sid = sid;
+ cseadd(fcr, cse);
+ return (cse);
+}
+
+void
+csefree(struct csession *cse)
+{
+ if (cse->key)
+ FREE(cse->key, M_XDATA);
+ if (cse->mackey)
+ FREE(cse->mackey, M_XDATA);
+ (void) crypto_freesession(cse->sid);
+ FREE(cse, M_XDATA);
+}
diff --git a/sys/crypto/cryptodev.h b/sys/crypto/cryptodev.h
new file mode 100644
index 00000000000..608465be174
--- /dev/null
+++ b/sys/crypto/cryptodev.h
@@ -0,0 +1,35 @@
+#include <sys/ioccom.h>
+
+struct session_op {
+ u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
+ u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
+
+ u_int32_t keylen; /* cipher key */
+ caddr_t key;
+ int mackeylen; /* mac key */
+ caddr_t mackey;
+
+ u_int32_t ses; /* returns: session # */
+};
+
+struct crypt_op {
+ u_int32_t ses;
+ u_int16_t op;
+ u_int16_t flags; /* always 0 */
+
+ u_int len;
+ caddr_t src, dst; /* become iov[] inside kernel */
+ caddr_t mac;
+ caddr_t iv;
+};
+
+#define COP_ENCRYPT 1
+#define COP_DECRYPT 2
+/* #define COP_SETKEY 3 */
+/* #define COP_GETKEY 4 */
+
+#define CRIOGET _IOR('c', 100, u_int32_t)
+
+#define CIOCGSESSION _IOWR('c', 101, struct session_op)
+#define CIOCFSESSION _IOW('c', 102, u_int32_t)
+#define CIOCCRYPT _IOWR('c', 103, struct crypt_op)
diff --git a/sys/crypto/cryptosoft.c b/sys/crypto/cryptosoft.c
index cfdf483b36f..4326d6d8832 100644
--- a/sys/crypto/cryptosoft.c
+++ b/sys/crypto/cryptosoft.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cryptosoft.c,v 1.18 2001/05/05 00:31:34 angelos Exp $ */
+/* $OpenBSD: cryptosoft.c,v 1.19 2001/05/13 15:39:27 deraadt Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
@@ -762,7 +762,7 @@ swcr_process(struct cryptop *crp)
for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next)
crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI);
- if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI)) == 0)
+ if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI), 0) == 0)
crp->crp_sid = nid;
}