? cryptodev.c.save ? cryptodev.diff ? o Index: cryptodev.c =================================================================== RCS file: /cvsroot/src/sys/opencrypto/cryptodev.c,v retrieving revision 1.126 diff -u -p -u -r1.126 cryptodev.c --- cryptodev.c 17 Apr 2025 12:59:58 -0000 1.126 +++ cryptodev.c 24 Apr 2026 22:19:50 -0000 @@ -101,11 +101,14 @@ __KERNEL_RCSID(0, "$NetBSD: cryptodev.c, #include "ioconf.h" kmutex_t cryptodev_mtx; +#define CRYPTODEV_OPS_MAX 1000000 struct csession { TAILQ_ENTRY(csession) next; + kmutex_t lock; u_int64_t sid; u_int32_t ses; + volatile u_int refcnt; u_int32_t cipher; /* note: shares name space in crd_alg */ const struct enc_xform *txform; @@ -116,27 +119,22 @@ struct csession { void * key; int keylen; - u_char tmp_iv[EALG_MAX_BLOCK_LEN]; void * mackey; int mackeylen; - u_char tmp_mac[CRYPTO_MAX_MAC_LEN]; - - struct iovec iovec[1]; /* user requests never have more */ - struct uio uio; - int error; }; struct fcrypt { TAILQ_HEAD(csessionlist, csession) csessions; TAILQ_HEAD(crprethead, cryptop) crp_ret_mq; TAILQ_HEAD(krprethead, cryptkop) crp_ret_mkq; - int sesn; + u_int32_t sesn; struct selinfo sinfo; u_int32_t requestid; struct timespec atime; struct timespec mtime; struct timespec btime; + kmutex_t lock; }; /* For our fixed-size allocations */ @@ -174,19 +172,18 @@ static const struct fileops cryptofops = .fo_restart = fnullop_restart, }; -struct csession *cryptodev_csefind(struct fcrypt *, u_int); -static struct csession *csefind(struct fcrypt *, u_int); -static int csedelete(struct fcrypt *, struct csession *); -static struct csession *cseadd(struct fcrypt *, struct csession *); -static struct csession *csecreate(struct fcrypt *, u_int64_t, void *, +static struct csession *cse_find(struct fcrypt *, u_int32_t); +static int cse_delete(struct fcrypt *, u_int32_t); +static struct csession *cse_add(struct fcrypt *, struct csession *); +static struct csession *cse_create(struct fcrypt *, u_int64_t, void *, u_int64_t, void *, u_int64_t, u_int32_t, u_int32_t, u_int32_t, const struct enc_xform *, const struct auth_hash *, const struct comp_algo *); -static void csefree(struct csession *); +static void cse_free(struct csession *); static int cryptodev_key(struct crypt_kop *); -static int cryptodev_mkey(struct fcrypt *, struct crypt_n_kop *, int); -static void cryptodev_msessionfin(struct fcrypt *, int, u_int32_t *); +static int cryptodev_mkey(struct fcrypt *, struct crypt_n_kop *, size_t); +static void cryptodev_msessionfin(struct fcrypt *, size_t, u_int32_t *); static void cryptodev_cb(struct cryptop *); static void cryptodevkey_cb(struct cryptkop *); @@ -198,6 +195,97 @@ static int cryptodev_getmstatus(struct int); static int cryptodev_getstatus(struct fcrypt *, struct crypt_result *); +static struct cryptop_data * +cod_ctor(struct cryptop_data *cod, struct csession *cse, size_t iov_len) +{ + memset(cod, 0, sizeof(*cod)); + cod->cse = cse; + cod->iov_len = iov_len; + cod->uio.uio_iovcnt = 1; + cod->uio.uio_resid = 0; + cod->uio.uio_rw = UIO_WRITE; + cod->uio.uio_iov = cod->iovec; + UIO_SETUP_SYSSPACE(&cod->uio); + + /* the iov needs to be big enough to handle the uncompressed data.... */ + cod->uio.uio_iov[0].iov_len = cod->iov_len; + if (cod->iov_len > 0) + cod->uio.uio_iov[0].iov_base = kmem_zalloc(iov_len, KM_SLEEP); + cod->uio.uio_resid = cod->uio.uio_iov[0].iov_len; + DPRINTF("lid[%u]: uio.iov_base %p malloced %zu bytes\n", + CRYPTO_SESID2LID(cse->sid), + cod->uio.uio_iov[0].iov_base, cod->iov_len); + return cod; +} + +static void +cod_dtor(struct cryptop_data *cod) +{ + DPRINTF("lid[%u]: uio.iov_base %p freeing %zu bytes\n", + CRYPTO_SESID2LID(cod->cse->sid), + cod->uio.uio_iov[0].iov_base, cod->iov_len); + if (cod->iov_len && cod->uio.uio_iov[0].iov_base) { + kmem_free(cod->uio.uio_iov[0].iov_base, cod->iov_len); + cod->uio.uio_iov[0].iov_base = NULL; + } +} + +static void +fcrypt_settime(struct fcrypt *fcr) +{ + mutex_enter(&fcr->lock); + fcr->mtime = fcr->atime; + mutex_exit(&fcr->lock); +} + +static struct fcrypt * +fcrypt_ctor(void) +{ + struct fcrypt *fcr; + + fcr = pool_get(&fcrpl, PR_WAITOK); + getnanotime(&fcr->btime); + fcr->atime = fcr->mtime = fcr->btime; + TAILQ_INIT(&fcr->csessions); + TAILQ_INIT(&fcr->crp_ret_mq); + TAILQ_INIT(&fcr->crp_ret_mkq); + selinit(&fcr->sinfo); + /* + * Don't ever return session 0, to allow detection of + * failed creation attempts with multi-create ioctl. + */ + fcr->sesn = 1; + fcr->requestid = 1; + mutex_init(&fcr->lock, MUTEX_DEFAULT, IPL_NONE); + + mutex_enter(&cryptodev_mtx); + crypto_refcount++; + mutex_exit(&cryptodev_mtx); + return fcr; +} + +static void +fcrypt_dtor(struct fcrypt *fcr) +{ + struct csession *cse; + + mutex_enter(&fcr->lock); + while ((cse = TAILQ_FIRST(&fcr->csessions))) { + TAILQ_REMOVE(&fcr->csessions, cse, next); + KASSERT(atomic_load_relaxed(&cse->refcnt) == 1); + cse_free(cse); + } + seldestroy(&fcr->sinfo); + mutex_exit(&fcr->lock); + mutex_destroy(&fcr->lock); + + mutex_enter(&cryptodev_mtx); + crypto_refcount--; + mutex_exit(&cryptodev_mtx); + + pool_put(&fcrpl, fcr); +} + /* * sysctl-able control variables for /dev/crypto now defined in crypto.c: * crypto_usercrypto, crypto_userasymcrypto, crypto_devallowsoft. @@ -239,187 +327,145 @@ cryptof_ioctl(struct file *fp, u_long cm u_int32_t ses; u_int32_t *sesid; int error = 0; - size_t count; + size_t count, len; /* backwards compatibility */ file_t *criofp; struct fcrypt *criofcr; int criofd; - mutex_enter(&cryptodev_mtx); + mutex_enter(&fcr->lock); getnanotime(&fcr->atime); - mutex_exit(&cryptodev_mtx); + mutex_exit(&fcr->lock); switch (cmd) { case CRIOGET: /* XXX deprecated, remove after 5.0 */ if ((error = fd_allocfile(&criofp, &criofd)) != 0) return error; - criofcr = pool_get(&fcrpl, PR_WAITOK); - mutex_enter(&cryptodev_mtx); - TAILQ_INIT(&criofcr->csessions); - TAILQ_INIT(&criofcr->crp_ret_mq); - TAILQ_INIT(&criofcr->crp_ret_mkq); - selinit(&criofcr->sinfo); - - /* - * Don't ever return session 0, to allow detection of - * failed creation attempts with multi-create ioctl. - */ - criofcr->sesn = 1; - criofcr->requestid = 1; - crypto_refcount++; - mutex_exit(&cryptodev_mtx); + criofcr = fcrypt_ctor(); (void)fd_clone(criofp, criofd, (FREAD|FWRITE), - &cryptofops, criofcr); + &cryptofops, criofcr); *(u_int32_t *)data = criofd; return error; break; case CIOCGSESSION: sop = (struct session_op *)data; error = cryptodev_session(fcr, sop); + DPRINTF("create(%#x) error = %d\n", sop->ses, error); break; case CIOCNGSESSION: sgop = (struct crypt_sgop *)data; - if (sgop->count <= 0 - || SIZE_MAX / sizeof(struct session_n_op) <= sgop->count) { + if (sgop->count <= 0 || sgop->count > CRYPTODEV_OPS_MAX + || SIZE_MAX / sizeof(*snop) <= sgop->count) { error = EINVAL; break; } - snop = kmem_alloc((sgop->count * - sizeof(struct session_n_op)), KM_SLEEP); - error = copyin(sgop->sessions, snop, sgop->count * - sizeof(struct session_n_op)); - if (error) { - goto mbail; - } - - mutex_enter(&cryptodev_mtx); - fcr->mtime = fcr->atime; - mutex_exit(&cryptodev_mtx); - error = cryptodev_msession(fcr, snop, sgop->count); - if (error) { - goto mbail; + len = sgop->count * sizeof(*snop); + snop = kmem_alloc(len, KM_SLEEP); + error = copyin(sgop->sessions, snop, len); + if (!error) { + fcrypt_settime(fcr); + error = cryptodev_msession(fcr, snop, sgop->count); + if (!error) { + error = copyout(snop, sgop->sessions, len); + } } - - error = copyout(snop, sgop->sessions, sgop->count * - sizeof(struct session_n_op)); -mbail: - kmem_free(snop, sgop->count * sizeof(struct session_n_op)); + kmem_free(snop, len); break; case CIOCFSESSION: - mutex_enter(&cryptodev_mtx); - fcr->mtime = fcr->atime; + fcrypt_settime(fcr); ses = *(u_int32_t *)data; - cse = csefind(fcr, ses); - if (cse == NULL) { - mutex_exit(&cryptodev_mtx); - return EINVAL; - } - csedelete(fcr, cse); - mutex_exit(&cryptodev_mtx); - csefree(cse); + mutex_enter(&fcr->lock); + error = cse_delete(fcr, ses); + mutex_exit(&fcr->lock); + DPRINTF("destroy(%#x) error = %d\n", ses, error); break; case CIOCNFSESSION: - mutex_enter(&cryptodev_mtx); - fcr->mtime = fcr->atime; - mutex_exit(&cryptodev_mtx); + fcrypt_settime(fcr); sfop = (struct crypt_sfop *)data; - if (sfop->count <= 0 - || SIZE_MAX / sizeof(u_int32_t) <= sfop->count) { + if (sfop->count <= 0 || sfop->count > CRYPTODEV_OPS_MAX + || SIZE_MAX / sizeof(*sesid) <= sfop->count) { error = EINVAL; break; } - sesid = kmem_alloc((sfop->count * sizeof(u_int32_t)), - KM_SLEEP); - error = copyin(sfop->sesid, sesid, - (sfop->count * sizeof(u_int32_t))); + len = sfop->count * sizeof(*sesid); + sesid = kmem_alloc(len, KM_SLEEP); + error = copyin(sfop->sesid, sesid, len); if (!error) { cryptodev_msessionfin(fcr, sfop->count, sesid); } - kmem_free(sesid, (sfop->count * sizeof(u_int32_t))); + kmem_free(sesid, len); break; case CIOCCRYPT: - mutex_enter(&cryptodev_mtx); - fcr->mtime = fcr->atime; + fcrypt_settime(fcr); cop = (struct crypt_op *)data; - cse = csefind(fcr, cop->ses); - mutex_exit(&cryptodev_mtx); + cse = cse_find(fcr, cop->ses); if (cse == NULL) { - DPRINTF("csefind failed\n"); + DPRINTF("cse_find failed %#x\n", cop->ses); return EINVAL; } error = cryptodev_op(cse, cop, curlwp); + cse_free(cse); DPRINTF("cryptodev_op error = %d\n", error); break; case CIOCNCRYPTM: - mutex_enter(&cryptodev_mtx); - fcr->mtime = fcr->atime; - mutex_exit(&cryptodev_mtx); + fcrypt_settime(fcr); mop = (struct crypt_mop *)data; - if (mop->count <= 0 - || SIZE_MAX / sizeof(struct crypt_n_op) <= mop->count) { + if (mop->count <= 0 || mop->count > CRYPTODEV_OPS_MAX + || SIZE_MAX / sizeof(*cnop) <= mop->count) { error = EINVAL; break; } - cnop = kmem_alloc((mop->count * sizeof(struct crypt_n_op)), - KM_SLEEP); - error = copyin(mop->reqs, cnop, - (mop->count * sizeof(struct crypt_n_op))); - if(!error) { + len = mop->count * sizeof(*cnop); + cnop = kmem_alloc(len, KM_SLEEP); + error = copyin(mop->reqs, cnop, len); + if (!error) { error = cryptodev_mop(fcr, cnop, mop->count, curlwp); if (!error) { - error = copyout(cnop, mop->reqs, - (mop->count * sizeof(struct crypt_n_op))); + error = copyout(cnop, mop->reqs, len); } } - kmem_free(cnop, (mop->count * sizeof(struct crypt_n_op))); + kmem_free(cnop, len); break; case CIOCKEY: error = cryptodev_key((struct crypt_kop *)data); DPRINTF("cryptodev_key error = %d\n", error); break; case CIOCNFKEYM: - mutex_enter(&cryptodev_mtx); - fcr->mtime = fcr->atime; - mutex_exit(&cryptodev_mtx); + fcrypt_settime(fcr); mkop = (struct crypt_mkop *)data; - if (mkop->count <= 0 - || SIZE_MAX / sizeof(struct crypt_n_kop) <= mkop->count) { + if (mkop->count <= 0 || mkop->count > CRYPTODEV_OPS_MAX + || SIZE_MAX / sizeof(*knop) <= mkop->count) { error = EINVAL; break; } - knop = kmem_alloc((mkop->count * sizeof(struct crypt_n_kop)), - KM_SLEEP); - error = copyin(mkop->reqs, knop, - (mkop->count * sizeof(struct crypt_n_kop))); + len = mkop->count * sizeof(*knop); + knop = kmem_alloc(len, KM_SLEEP); + error = copyin(mkop->reqs, knop, len); if (!error) { error = cryptodev_mkey(fcr, knop, mkop->count); if (!error) - error = copyout(knop, mkop->reqs, - (mkop->count * sizeof(struct crypt_n_kop))); + error = copyout(knop, mkop->reqs, len); } - kmem_free(knop, (mkop->count * sizeof(struct crypt_n_kop))); + kmem_free(knop, len); break; case CIOCASYMFEAT: error = crypto_getfeat((int *)data); break; case CIOCNCRYPTRETM: - mutex_enter(&cryptodev_mtx); - fcr->mtime = fcr->atime; - mutex_exit(&cryptodev_mtx); + fcrypt_settime(fcr); crypt_ret = (struct cryptret *)data; - count = crypt_ret->count; - if (count <= 0 - || SIZE_MAX / sizeof(struct crypt_result) <= count) { + if (crypt_ret->count <= 0 + || SIZE_MAX / sizeof(*crypt_res) <= crypt_ret->count) { error = EINVAL; break; } - crypt_res = kmem_alloc((count * sizeof(struct crypt_result)), - KM_SLEEP); - error = copyin(crypt_ret->results, crypt_res, - (count * sizeof(struct crypt_result))); + len = crypt_ret->count * sizeof(*crypt_res); + crypt_res = kmem_alloc(len, KM_SLEEP); + error = copyin(crypt_ret->results, crypt_res, len); if (error) goto reterr; + count = crypt_ret->count; crypt_ret->count = cryptodev_getmstatus(fcr, crypt_res, crypt_ret->count); /* sanity check count */ @@ -430,10 +476,9 @@ mbail: crypt_ret->count = count; } - error = copyout(crypt_res, crypt_ret->results, - (crypt_ret->count * sizeof(struct crypt_result))); + error = copyout(crypt_res, crypt_ret->results, len); reterr: - kmem_free(crypt_res, (count * sizeof(struct crypt_result))); + kmem_free(crypt_res, len); break; case CIOCNCRYPTRET: error = cryptodev_getstatus(fcr, (struct crypt_result *)data); @@ -454,11 +499,12 @@ int cryptodev_op(struct csession *cse, struct crypt_op *cop, struct lwp *l) { struct cryptop *crp = NULL; + struct cryptop_data *cod = NULL; struct cryptodesc *crde = NULL, *crda = NULL, *crdc = NULL; int error; - int iov_len = cop->len; + size_t iov_len = cop->len; int flags=0; - int dst_len; /* copyout size */ + size_t dst_len; /* copyout size */ if (cop->len > 256*1024-4) return E2BIG; @@ -474,39 +520,24 @@ cryptodev_op(struct csession *cse, struc if (cse->tcomp == NULL && cse->txform == NULL && cse->thash == NULL) return EINVAL; - DPRINTF("cryptodev_op[%u]: iov_len %d\n", + DPRINTF("[%u]: iov_len %zu\n", CRYPTO_SESID2LID(cse->sid), iov_len); if ((cse->tcomp) && cop->dst_len) { if (iov_len < cop->dst_len) { /* Need larger iov to deal with decompress */ iov_len = cop->dst_len; } - DPRINTF("cryptodev_op: iov_len -> %d for decompress\n", iov_len); + DPRINTF("iov_len -> %zu for decompress\n", iov_len); } - (void)memset(&cse->uio, 0, sizeof(cse->uio)); - cse->uio.uio_iovcnt = 1; - cse->uio.uio_resid = 0; - cse->uio.uio_rw = UIO_WRITE; - cse->uio.uio_iov = cse->iovec; - UIO_SETUP_SYSSPACE(&cse->uio); - memset(&cse->iovec, 0, sizeof(cse->iovec)); - - /* the iov needs to be big enough to handle the uncompressed - * data.... */ - cse->uio.uio_iov[0].iov_len = iov_len; - if (iov_len > 0) - cse->uio.uio_iov[0].iov_base = kmem_alloc(iov_len, KM_SLEEP); - cse->uio.uio_resid = cse->uio.uio_iov[0].iov_len; - DPRINTF("lid[%u]: uio.iov_base %p malloced %d bytes\n", - CRYPTO_SESID2LID(cse->sid), - cse->uio.uio_iov[0].iov_base, iov_len); - crp = crypto_getreq((cse->tcomp != NULL) + (cse->txform != NULL) + (cse->thash != NULL)); + crp = crypto_getreq((cse->tcomp != NULL) + + (cse->txform != NULL) + (cse->thash != NULL)); if (crp == NULL) { error = ENOMEM; goto bail; } + cod = cod_ctor(&crp->cod, cse, iov_len); DPRINTF("lid[%u]: crp %p\n", CRYPTO_SESID2LID(cse->sid), crp); /* crds are always ordered tcomp, thash, then txform */ @@ -535,10 +566,10 @@ cryptodev_op(struct csession *cse, struc DPRINTF("ocf[%u]: iov_len %zu, cop->len %u\n", CRYPTO_SESID2LID(cse->sid), - cse->uio.uio_iov[0].iov_len, + cod->uio.uio_iov[0].iov_len, cop->len); - if ((error = copyin(cop->src, cse->uio.uio_iov[0].iov_base, cop->len))) + if ((error = copyin(cop->src, cod->uio.uio_iov[0].iov_base, cop->len))) { printf("copyin failed %s %d \n", (char *)cop->src, error); goto bail; @@ -608,10 +639,10 @@ cryptodev_op(struct csession *cse, struc crp->crp_ilen = cop->len; crp->crp_flags = CRYPTO_F_IOV | (cop->flags & COP_F_BATCH) | flags; - crp->crp_buf = (void *)&cse->uio; + crp->crp_buf = (void *)&cod->uio; crp->crp_callback = cryptodev_cb; crp->crp_sid = cse->sid; - crp->crp_opaque = cse; + crp->crp_opaque = cod; if (cop->iv) { if (crde == NULL) { @@ -622,10 +653,10 @@ cryptodev_op(struct csession *cse, struc error = EINVAL; goto bail; } - if ((error = copyin(cop->iv, cse->tmp_iv, + if ((error = copyin(cop->iv, crp->tmp_iv, cse->txform->ivsize))) goto bail; - (void)memcpy(crde->crd_iv, cse->tmp_iv, cse->txform->ivsize); + (void)memcpy(crde->crd_iv, crp->tmp_iv, cse->txform->ivsize); crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; crde->crd_skip = 0; } else if (crde) { @@ -644,18 +675,18 @@ cryptodev_op(struct csession *cse, struc error = EINVAL; goto bail; } - crp->crp_mac = cse->tmp_mac; + crp->crp_mac = crp->tmp_mac; } cv_init(&crp->crp_cv, "crydev"); crypto_dispatch(crp); - mutex_enter(&cryptodev_mtx); + mutex_enter(&cse->lock); while (!(crp->crp_devflags & CRYPTODEV_F_RET)) { - DPRINTF("cse->sid[%d]: sleeping on cv %p for crp %p\n", - (uint32_t)cse->sid, &crp->crp_cv, crp); - cv_wait(&crp->crp_cv, &cryptodev_mtx); /* XXX cv_wait_sig? */ + DPRINTF("cse->sid[%u]: sleeping on cv %p for crp %p\n", + (u_int32_t)cse->sid, &crp->crp_cv, crp); + cv_wait(&crp->crp_cv, &cse->lock); /* XXX cv_wait_sig? */ } - mutex_exit(&cryptodev_mtx); + mutex_exit(&cse->lock); cv_destroy(&crp->crp_cv); if (crp->crp_etype != 0) { @@ -664,12 +695,6 @@ cryptodev_op(struct csession *cse, struc goto bail; } - if (cse->error) { - DPRINTF("cse->error %d\n", cse->error); - error = cse->error; - goto bail; - } - dst_len = crp->crp_ilen; /* let the user know how much data was returned */ if (crp->crp_olen) { @@ -681,10 +706,10 @@ cryptodev_op(struct csession *cse, struc } if (cop->dst) { - DPRINTF("copyout %d bytes to %p\n", dst_len, cop->dst); + DPRINTF("copyout %zu bytes to %p\n", dst_len, cop->dst); } if (cop->dst && - (error = copyout(cse->uio.uio_iov[0].iov_base, cop->dst, dst_len))) + (error = copyout(cod->uio.uio_iov[0].iov_base, cop->dst, dst_len))) { DPRINTF("copyout error %d\n", error); goto bail; @@ -698,59 +723,55 @@ cryptodev_op(struct csession *cse, struc bail: - if (crp) { + if (cod) + cod_dtor(cod); + if (crp) crypto_freereq(crp); - } - if (cse->uio.uio_iov[0].iov_base) { - kmem_free(cse->uio.uio_iov[0].iov_base,iov_len); - } - return error; } static void cryptodev_cb(struct cryptop *crp) { - struct csession *cse = crp->crp_opaque; + struct cryptop_data *cod = crp->crp_opaque; + DPRINTF("cod = %p\n", cod); - mutex_enter(&cryptodev_mtx); - cse->error = crp->crp_etype; + mutex_enter(&cod->cse->lock); crp->crp_devflags |= CRYPTODEV_F_RET; cv_signal(&crp->crp_cv); - mutex_exit(&cryptodev_mtx); + mutex_exit(&cod->cse->lock); } static void cryptodev_mcb(struct cryptop *crp) { - struct csession *cse = crp->crp_opaque; + struct cryptop_data *cod = crp->crp_opaque; - mutex_enter(&cryptodev_mtx); - cse->error = crp->crp_etype; + mutex_enter(&cod->cse->lock); TAILQ_INSERT_TAIL(&crp->fcrp->crp_ret_mq, crp, crp_next); selnotify(&crp->fcrp->sinfo, 0, 0); - mutex_exit(&cryptodev_mtx); + mutex_exit(&cod->cse->lock); } static void cryptodevkey_cb(struct cryptkop *krp) { - mutex_enter(&cryptodev_mtx); + mutex_enter(&krp->krp_lock); krp->krp_devflags |= CRYPTODEV_F_RET; cv_signal(&krp->krp_cv); - mutex_exit(&cryptodev_mtx); + mutex_exit(&krp->krp_lock); } static void cryptodevkey_mcb(struct cryptkop *krp) { - mutex_enter(&cryptodev_mtx); + mutex_enter(&krp->krp_lock); cv_signal(&krp->krp_cv); TAILQ_INSERT_TAIL(&krp->fcrp->crp_ret_mkq, krp, krp_next); selnotify(&krp->fcrp->sinfo, 0, 0); - mutex_exit(&cryptodev_mtx); + mutex_exit(&krp->krp_lock); } static int @@ -758,7 +779,7 @@ cryptodev_key(struct crypt_kop *kop) { struct cryptkop *krp = NULL; int error = EINVAL; - int in, out, size, i; + size_t in, out, size, i; if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) return EFBIG; @@ -821,6 +842,7 @@ cryptodev_key(struct crypt_kop *kop) } (void)memset(krp, 0, sizeof *krp); cv_init(&krp->krp_cv, "crykdev"); + mutex_init(&krp->krp_lock, MUTEX_DEFAULT, IPL_NONE); krp->krp_op = kop->crk_op; krp->krp_status = kop->crk_status; krp->krp_iparams = kop->crk_iparams; @@ -845,11 +867,11 @@ cryptodev_key(struct crypt_kop *kop) crypto_kdispatch(krp); - mutex_enter(&cryptodev_mtx); + mutex_enter(&krp->krp_lock); while (!(krp->krp_devflags & CRYPTODEV_F_RET)) { - cv_wait(&krp->krp_cv, &cryptodev_mtx); /* XXX cv_wait_sig? */ + cv_wait(&krp->krp_cv, &krp->krp_lock); /* XXX cv_wait_sig? */ } - mutex_exit(&cryptodev_mtx); + mutex_exit(&krp->krp_lock); if (krp->krp_status != 0) { DPRINTF("krp->krp_status 0x%08x\n", krp->krp_status); @@ -865,7 +887,7 @@ cryptodev_key(struct crypt_kop *kop) error = copyout(krp->krp_param[i].crp_p, kop->crk_param[i].crp_p, size); if (error) { - DPRINTF("copyout oparam %d failed, " + DPRINTF("copyout oparam %zu failed, " "error=%d\n", i-krp->krp_iparams, error); goto fail; } @@ -888,80 +910,83 @@ fail: return error; } + /* ARGSUSED */ static int cryptof_close(struct file *fp) { struct fcrypt *fcr = fp->f_fcrypt; - struct csession *cse; - mutex_enter(&cryptodev_mtx); - while ((cse = TAILQ_FIRST(&fcr->csessions))) { - TAILQ_REMOVE(&fcr->csessions, cse, next); - mutex_exit(&cryptodev_mtx); - csefree(cse); - mutex_enter(&cryptodev_mtx); - } - seldestroy(&fcr->sinfo); fp->f_fcrypt = NULL; - crypto_refcount--; - mutex_exit(&cryptodev_mtx); - - pool_put(&fcrpl, fcr); + fcrypt_dtor(fcr); return 0; } /* needed for compatibility module */ -struct csession *cryptodev_csefind(struct fcrypt *fcr, u_int ses) +struct csession * +cryptodev_cse_find(struct fcrypt *fcr, u_int ses) +{ + return cse_find(fcr, ses); +} + +/* needed for compatibility module */ +void +cryptodev_cse_free(struct csession *cse) { - return csefind(fcr, ses); + cse_free(cse); } -/* csefind: call with cryptodev_mtx held. */ static struct csession * -csefind(struct fcrypt *fcr, u_int ses) +cse_find(struct fcrypt *fcr, u_int ses) { - struct csession *cse, *cnext, *ret = NULL; + struct csession *cse, *cnext; - KASSERT(mutex_owned(&cryptodev_mtx)); + mutex_enter(&fcr->lock); TAILQ_FOREACH_SAFE(cse, &fcr->csessions, next, cnext) - if (cse->ses == ses) - ret = cse; + if (cse->ses == ses) { + mutex_exit(&fcr->lock); + atomic_inc_uint(&cse->refcnt); + return cse; + } + mutex_exit(&fcr->lock); - return ret; + return NULL; } -/* csedelete: call with cryptodev_mtx held. */ static int -csedelete(struct fcrypt *fcr, struct csession *cse_del) +cse_delete(struct fcrypt *fcr, u_int32_t ses) { struct csession *cse, *cnext; - int ret = 0; - KASSERT(mutex_owned(&cryptodev_mtx)); TAILQ_FOREACH_SAFE(cse, &fcr->csessions, next, cnext) { - if (cse == cse_del) { + if (cse->ses == ses) { + if (atomic_load_relaxed(&cse->refcnt) != 1) + return EBUSY; TAILQ_REMOVE(&fcr->csessions, cse, next); - ret = 1; + cse_free(cse); + return 0; } } - return ret; + return EINVAL; } static struct csession * -cseadd(struct fcrypt *fcr, struct csession *cse) +cse_add(struct fcrypt *fcr, struct csession *cse) { - mutex_enter(&cryptodev_mtx); + mutex_enter(&fcr->lock); /* don't let session ID wrap! */ - if (fcr->sesn + 1 == 0) return NULL; + if (fcr->sesn + 1 == 0) { + mutex_exit(&fcr->lock); + return NULL; + } TAILQ_INSERT_TAIL(&fcr->csessions, cse, next); cse->ses = fcr->sesn++; - mutex_exit(&cryptodev_mtx); + mutex_exit(&fcr->lock); return cse; } static struct csession * -csecreate(struct fcrypt *fcr, u_int64_t sid, void *key, u_int64_t keylen, +cse_create(struct fcrypt *fcr, u_int64_t sid, void *key, u_int64_t keylen, void *mackey, u_int64_t mackeylen, u_int32_t cipher, u_int32_t mac, u_int32_t comp_alg, const struct enc_xform *txform, const struct auth_hash *thash, const struct comp_algo *tcomp) @@ -972,6 +997,8 @@ csecreate(struct fcrypt *fcr, u_int64_t if (cse == NULL) return NULL; cse->key = key; + mutex_init(&cse->lock, MUTEX_DEFAULT, IPL_NONE); + cse->refcnt = 1; cse->keylen = keylen/8; cse->mackey = mackey; cse->mackeylen = mackeylen/8; @@ -982,19 +1009,24 @@ csecreate(struct fcrypt *fcr, u_int64_t cse->txform = txform; cse->thash = thash; cse->tcomp = tcomp; - cse->error = 0; - if (cseadd(fcr, cse)) + if (cse_add(fcr, cse)) { + DPRINTF("created %p\n", cse); return cse; - else { - pool_put(&csepl, cse); - return NULL; } + + mutex_destroy(&cse->lock); + pool_put(&csepl, cse); + return NULL; } static void -csefree(struct csession *cse) +cse_free(struct csession *cse) { + DPRINTF("destroying %p %d\n", cse, atomic_load_relaxed(&cse->refcnt)); + if (atomic_dec_uint_nv(&cse->refcnt) > 0) + return; + mutex_destroy(&cse->lock); crypto_freesession(cse->sid); if (cse->key) free(cse->key, M_XDATA); @@ -1017,22 +1049,7 @@ cryptoopen(dev_t dev, int flag, int mode if ((error = fd_allocfile(&fp, &fd)) != 0) return error; - fcr = pool_get(&fcrpl, PR_WAITOK); - getnanotime(&fcr->btime); - fcr->atime = fcr->mtime = fcr->btime; - mutex_enter(&cryptodev_mtx); - TAILQ_INIT(&fcr->csessions); - TAILQ_INIT(&fcr->crp_ret_mq); - TAILQ_INIT(&fcr->crp_ret_mkq); - selinit(&fcr->sinfo); - /* - * Don't ever return session 0, to allow detection of - * failed creation attempts with multi-create ioctl. - */ - fcr->sesn = 1; - fcr->requestid = 1; - crypto_refcount++; - mutex_exit(&cryptodev_mtx); + fcr = fcrypt_ctor(); return fd_clone(fp, fd, flag, &cryptofops, fcr); } @@ -1073,25 +1090,24 @@ struct cdevsw crypto_cdevsw = { int cryptodev_mop(struct fcrypt *fcr, struct crypt_n_op * cnop, - int count, struct lwp *l) + size_t count, struct lwp *l) { struct cryptop *crp = NULL; + struct cryptop_data *cod = NULL; struct cryptodesc *crde = NULL, *crda = NULL, *crdc = NULL; - int req, error=0; + int error = 0; struct csession *cse; int flags=0; - int iov_len; + size_t req, iov_len; + for (req = 0; req < count; req++) { - mutex_enter(&cryptodev_mtx); - cse = csefind(fcr, cnop[req].ses); + cse = cse_find(fcr, cnop[req].ses); if (cse == NULL) { - DPRINTF("csefind failed\n"); + DPRINTF("cse_find failed %#x\n", cnop[req].ses); cnop[req].status = EINVAL; - mutex_exit(&cryptodev_mtx); continue; } - mutex_exit(&cryptodev_mtx); if (cnop[req].len > 256*1024-4) { DPRINTF("length failed\n"); @@ -1137,20 +1153,10 @@ cryptodev_mop(struct fcrypt *fcr, /* Need larger iov to deal with decompress */ iov_len = cnop[req].dst_len; } - DPRINTF("iov_len -> %d for decompress\n", iov_len); + DPRINTF("iov_len -> %zu for decompress\n", iov_len); } - (void)memset(&crp->uio, 0, sizeof(crp->uio)); - crp->uio.uio_iovcnt = 1; - crp->uio.uio_resid = 0; - crp->uio.uio_rw = UIO_WRITE; - crp->uio.uio_iov = crp->iovec; - UIO_SETUP_SYSSPACE(&crp->uio); - memset(&crp->iovec, 0, sizeof(crp->iovec)); - crp->uio.uio_iov[0].iov_len = iov_len; - DPRINTF("kmem_alloc(%d) for iov \n", iov_len); - crp->uio.uio_iov[0].iov_base = kmem_alloc(iov_len, KM_SLEEP); - crp->uio.uio_resid = crp->uio.uio_iov[0].iov_len; + cod = cod_ctor(&crp->cod, cse, iov_len); if (cse->tcomp) { crdc = crp->crp_desc; @@ -1170,7 +1176,7 @@ cryptodev_mop(struct fcrypt *fcr, } if ((copyin(cnop[req].src, - crp->uio.uio_iov[0].iov_base, cnop[req].len))) { + cod->uio.uio_iov[0].iov_base, cnop[req].len))) { cnop[req].status = EINVAL; goto bail; } @@ -1198,7 +1204,7 @@ cryptodev_mop(struct fcrypt *fcr, crdc->crd_klen = 0; DPRINTF("cse->sid[%d]: crdc setup for comp_alg %d" " len %d.\n", - (uint32_t)cse->sid, crdc->crd_alg, + (u_int32_t)cse->sid, crdc->crd_alg, crdc->crd_len); } @@ -1240,16 +1246,16 @@ cryptodev_mop(struct fcrypt *fcr, crp->crp_ilen = cnop[req].len; crp->crp_flags = CRYPTO_F_IOV | (cnop[req].flags & COP_F_BATCH) | flags; - crp->crp_buf = (void *)&crp->uio; + crp->crp_buf = (void *)&cod->uio; crp->crp_callback = cryptodev_mcb; crp->crp_sid = cse->sid; - crp->crp_opaque = cse; + crp->crp_opaque = cod; crp->fcrp = fcr; crp->dst = cnop[req].dst; crp->len = cnop[req].len; /* input len, iov may be larger */ crp->mac = cnop[req].mac; DPRINTF("iov_base %p dst %p len %d mac %p\n", - crp->uio.uio_iov[0].iov_base, crp->dst, crp->len, + cod->uio.uio_iov[0].iov_base, crp->dst, crp->len, crp->mac); if (cnop[req].iv) { @@ -1286,7 +1292,7 @@ cryptodev_mop(struct fcrypt *fcr, cnop[req].status = EINVAL; goto bail; } - crp->crp_mac=cse->tmp_mac; + crp->crp_mac = crp->tmp_mac; } cnop[req].reqid = atomic_inc_32_nv(&(fcr->requestid)); crp->crp_reqid = cnop[req].reqid; @@ -1297,13 +1303,12 @@ cryptodev_mop(struct fcrypt *fcr, cv_destroy(&crp->crp_cv); bail: if (cnop[req].status) { - if (crp) { - if (crp->uio.uio_iov[0].iov_base) { - kmem_free(crp->uio.uio_iov[0].iov_base, - crp->uio.uio_iov[0].iov_len); - } + DPRINTF("%zu status %d\n", req, cnop[req].status); + cse_free(cse); + if (cod) + cod_dtor(cod); + if (crp) crypto_freereq(crp); - } error = 0; } } @@ -1311,11 +1316,11 @@ bail: } static int -cryptodev_mkey(struct fcrypt *fcr, struct crypt_n_kop *kop, int count) +cryptodev_mkey(struct fcrypt *fcr, struct crypt_n_kop *kop, size_t count) { struct cryptkop *krp = NULL; int error = EINVAL; - int in, out, size, i, req; + size_t in, out, size, i, req; for (req = 0; req < count; req++) { if (kop[req].crk_iparams + kop[req].crk_oparams > CRK_MAXPARAM) @@ -1654,8 +1659,8 @@ cryptodev_session(struct fcrypt *fcr, st error = crypto_newsession(&sid, crihead, crypto_devallowsoft); if (!error) { - DPRINTF("got session %d\n", (uint32_t)sid); - cse = csecreate(fcr, sid, crie.cri_key, crie.cri_klen, + DPRINTF("got session %d\n", (u_int32_t)sid); + cse = cse_create(fcr, sid, crie.cri_key, crie.cri_klen, cria.cri_key, cria.cri_klen, (txform ? sop->cipher : 0), sop->mac, (tcomp ? sop->comp_alg : 0), txform, thash, tcomp); if (cse != NULL) { @@ -1684,9 +1689,9 @@ bail: int cryptodev_msession(struct fcrypt *fcr, struct session_n_op *sn_ops, - int count) + size_t count) { - int i; + size_t i; for (i = 0; i < count; i++, sn_ops++) { struct session_op s_op; @@ -1700,7 +1705,9 @@ cryptodev_msession(struct fcrypt *fcr, s s_op.ses = ~0; sn_ops->status = cryptodev_session(fcr, &s_op); - + if (sn_ops->status) { + DPRINTF("%zu: create failed %d\n", i, sn_ops->status); + } sn_ops->ses = s_op.ses; } @@ -1708,22 +1715,14 @@ cryptodev_msession(struct fcrypt *fcr, s } static void -cryptodev_msessionfin(struct fcrypt *fcr, int count, u_int32_t *sesid) +cryptodev_msessionfin(struct fcrypt *fcr, size_t count, u_int32_t *sesid) { - struct csession *cse; - int req; - - mutex_enter(&cryptodev_mtx); - for(req = 0; req < count; req++) { - cse = csefind(fcr, sesid[req]); - if (cse == NULL) - continue; - csedelete(fcr, cse); - mutex_exit(&cryptodev_mtx); - csefree(cse); - mutex_enter(&cryptodev_mtx); + mutex_enter(&fcr->lock); + for (size_t req = 0; req < count; req++) { + // XXX: What to do if busy? + cse_delete(fcr, sesid[req]); } - mutex_exit(&cryptodev_mtx); + mutex_exit(&fcr->lock); } /* @@ -1737,7 +1736,6 @@ cryptodev_getmstatus(struct fcrypt *fcr, { struct cryptop *crp = NULL; struct cryptkop *krp = NULL; - struct csession *cse; int i, size, req = 0; int completed=0; @@ -1754,25 +1752,16 @@ cryptodev_getmstatus(struct fcrypt *fcr, * if 3 then 2 symmetric and 1 asymmetric and so on */ /* pull off a list of requests while protected from changes */ - mutex_enter(&cryptodev_mtx); + mutex_enter(&fcr->lock); while (req < count) { crp = TAILQ_FIRST(&fcr->crp_ret_mq); if (crp) { TAILQ_REMOVE(&fcr->crp_ret_mq, crp, crp_next); TAILQ_INSERT_TAIL(&crp_delfree_q, crp, crp_next); - cse = (struct csession *)crp->crp_opaque; - - /* see if the session is still valid */ - cse = csefind(fcr, cse->ses); - if (cse != NULL) { - crypt_res[req].status = 0; - } else { - DPRINTF("csefind failed\n"); - crypt_res[req].status = EINVAL; - } + crypt_res[req].status = 0; req++; } - if(req < count) { + if (req < count) { crypt_res[req].status = 0; krp = TAILQ_FIRST(&fcr->crp_ret_mkq); if (krp) { @@ -1782,17 +1771,17 @@ cryptodev_getmstatus(struct fcrypt *fcr, } } } - mutex_exit(&cryptodev_mtx); + mutex_exit(&fcr->lock); /* now do all the work outside the mutex */ for(req=0; req < count ;) { crp = TAILQ_FIRST(&crp_delfree_q); if (crp) { + struct cryptop_data *cod = crp->crp_opaque; if (crypt_res[req].status != 0) { - /* csefind failed during collection */ + /* cse_find failed during collection */ goto bail; } - cse = (struct csession *)crp->crp_opaque; crypt_res[req].reqid = crp->crp_reqid; crypt_res[req].opaque = crp->crp_usropaque; completed++; @@ -1802,25 +1791,20 @@ cryptodev_getmstatus(struct fcrypt *fcr, goto bail; } - if (cse->error) { - crypt_res[req].status = cse->error; - goto bail; - } - if (crp->dst && (crypt_res[req].status = - copyout(crp->uio.uio_iov[0].iov_base, crp->dst, + copyout(cod->uio.uio_iov[0].iov_base, crp->dst, crp->len))) goto bail; if (crp->mac && (crypt_res[req].status = copyout(crp->crp_mac, crp->mac, - cse->thash->authsize))) + cod->cse->thash->authsize))) goto bail; bail: TAILQ_REMOVE(&crp_delfree_q, crp, crp_next); - kmem_free(crp->uio.uio_iov[0].iov_base, - crp->uio.uio_iov[0].iov_len); + cse_free(cod->cse); + cod_dtor(cod); crypto_freereq(crp); req++; } @@ -1883,46 +1867,34 @@ cryptodev_getstatus (struct fcrypt *fcr, { struct cryptop *crp = NULL, *cnext; struct cryptkop *krp = NULL, *knext; - struct csession *cse; int i, size, req = 0; - mutex_enter(&cryptodev_mtx); + mutex_enter(&fcr->lock); /* Here we dont know for which request the user is requesting the * response so checking in both the queues */ TAILQ_FOREACH_SAFE(crp, &fcr->crp_ret_mq, crp_next, cnext) { if(crp && (crp->crp_reqid == crypt_res->reqid)) { - cse = (struct csession *)crp->crp_opaque; + struct cryptop_data *cod = crp->crp_opaque; crypt_res->opaque = crp->crp_usropaque; - cse = csefind(fcr, cse->ses); - if (cse == NULL) { - DPRINTF("csefind failed\n"); - crypt_res->status = EINVAL; - goto bail; - } - if (crp->crp_etype != 0) { crypt_res->status = crp->crp_etype; goto bail; } - if (cse->error) { - crypt_res->status = cse->error; - goto bail; - } - if (crp->dst && (crypt_res->status = - copyout(crp->uio.uio_iov[0].iov_base, + copyout(cod->uio.uio_iov[0].iov_base, crp->dst, crp->len))) goto bail; if (crp->mac && (crypt_res->status = copyout(crp->crp_mac, crp->mac, - cse->thash->authsize))) + cod->cse->thash->authsize))) goto bail; bail: TAILQ_REMOVE(&fcr->crp_ret_mq, crp, crp_next); - - mutex_exit(&cryptodev_mtx); + mutex_exit(&fcr->lock); + cse_free(cod->cse); + cod_dtor(cod); crypto_freereq(crp); return 0; } @@ -1956,7 +1928,7 @@ bail: } fail: TAILQ_REMOVE(&fcr->crp_ret_mkq, krp, krp_next); - mutex_exit(&cryptodev_mtx); + mutex_exit(&fcr->lock); /* not sure what to do for this */ /* kop[req].crk_status = krp->krp_status; */ for (i = 0; i < CRK_MAXPARAM; i++) { @@ -1973,7 +1945,7 @@ fail: return 0; } } - mutex_exit(&cryptodev_mtx); + mutex_exit(&fcr->lock); return EINPROGRESS; } @@ -1984,14 +1956,14 @@ cryptof_stat(struct file *fp, struct sta (void)memset(st, 0, sizeof(*st)); - mutex_enter(&cryptodev_mtx); + mutex_enter(&fcr->lock); st->st_dev = makedev(cdevsw_lookup_major(&crypto_cdevsw), fcr->sesn); st->st_atimespec = fcr->atime; st->st_mtimespec = fcr->mtime; st->st_ctimespec = st->st_birthtimespec = fcr->btime; st->st_uid = kauth_cred_geteuid(fp->f_cred); st->st_gid = kauth_cred_getegid(fp->f_cred); - mutex_exit(&cryptodev_mtx); + mutex_exit(&fcr->lock); return 0; } @@ -2007,7 +1979,7 @@ cryptof_poll(struct file *fp, int events return 0; } - mutex_enter(&cryptodev_mtx); + mutex_enter(&fcr->lock); if (TAILQ_EMPTY(&fcr->crp_ret_mq) && TAILQ_EMPTY(&fcr->crp_ret_mkq)) { /* no completed requests pending, save the poll for later */ selrecord(curlwp, &fcr->sinfo); @@ -2015,7 +1987,7 @@ cryptof_poll(struct file *fp, int events /* let the app(s) know that there are completed requests */ revents = events & (POLLIN | POLLRDNORM); } - mutex_exit(&cryptodev_mtx); + mutex_exit(&fcr->lock); return revents; } @@ -2050,7 +2022,7 @@ cryptoattach(int num) void crypto_attach(device_t, device_t, void *); void -crypto_attach(device_t parent, device_t self, void * opaque) +crypto_attach(device_t parent, device_t self, void *opaque) { cryptoattach(0); Index: cryptodev.h =================================================================== RCS file: /cvsroot/src/sys/opencrypto/cryptodev.h,v retrieving revision 1.51 diff -u -p -u -r1.51 cryptodev.h --- cryptodev.h 11 Jul 2023 10:42:16 -0000 1.51 +++ cryptodev.h 24 Apr 2026 22:19:50 -0000 @@ -165,7 +165,7 @@ struct session_op { u_int32_t keylen; /* cipher key */ void * key; - int mackeylen; /* mac key */ + u_int32_t mackeylen; /* mac key */ void * mackey; u_int32_t ses; /* returns: session # */ @@ -180,7 +180,7 @@ struct session_n_op { u_int32_t keylen; /* cipher key */ void * key; - int mackeylen; /* mac key */ + u_int32_t mackeylen; /* mac key */ void * mackey; u_int32_t ses; /* returns: session # */ @@ -196,7 +196,7 @@ struct crypt_op { #define COP_DECOMP 4 u_int16_t flags; #define COP_F_BATCH 0x0008 /* Dispatch as quickly as possible */ - u_int len; /* src len */ + u_int32_t len; /* src len */ void * src, *dst; /* become iov[] inside kernel */ void * mac; /* must be big enough for chosen MAC */ void * iv; @@ -226,7 +226,7 @@ struct crypt_n_op { u_int16_t flags; #define COP_F_BATCH 0x0008 /* Dispatch as quickly as possible */ #define COP_F_MORE 0x0010 /* more data to follow */ - u_int len; /* src len */ + u_int32_t len; /* src len */ u_int32_t reqid; /* request id */ int status; /* status of request -accepted or not */ @@ -239,7 +239,7 @@ struct crypt_n_op { void * src, *dst; /* become iov[] inside kernel */ void * mac; /* must be big enough for chosen MAC */ void * iv; - u_int dst_len; /* dst len if not 0 */ + u_int32_t dst_len; /* dst len if not 0 */ }; /* CIOCNCRYPTM ioctl argument, supporting one or more asynchronous @@ -268,17 +268,17 @@ struct crypt_sgop { /* bignum parameter, in packed bytes, ... */ struct crparam { void * crp_p; - u_int crp_nbits; + u_int32_t crp_nbits; }; #define CRK_MAXPARAM 8 struct crypt_kop { - u_int crk_op; /* ie. CRK_MOD_EXP or other */ - u_int crk_status; /* return status */ - u_short crk_iparams; /* # of input parameters */ - u_short crk_oparams; /* # of output parameters */ - u_int crk_pad1; + u_int32_t crk_op; /* ie. CRK_MOD_EXP or other */ + u_int32_t crk_status; /* return status */ + u_int16_t crk_iparams; /* # of input parameters */ + u_int16_t crk_oparams; /* # of output parameters */ + u_int32_t crk_pad1; struct crparam crk_param[CRK_MAXPARAM]; }; @@ -295,10 +295,10 @@ struct crypt_kop { * user application. */ struct crypt_n_kop { - u_int crk_op; /* ie. CRK_MOD_EXP or other */ - u_int crk_status; /* return status */ - u_short crk_iparams; /* # of input parameters */ - u_short crk_oparams; /* # of output parameters */ + u_int32_t crk_op; /* ie. CRK_MOD_EXP or other */ + u_int32_t crk_status; /* return status */ + u_int16_t crk_iparams; /* # of input parameters */ + u_int16_t crk_oparams; /* # of output parameters */ u_int32_t crk_reqid; /* request id */ struct crparam crk_param[CRK_MAXPARAM]; void *crk_opaque; /* opaque pointer returned to user */ @@ -423,8 +423,8 @@ struct uio; /* Standard initialization structure beginning */ struct cryptoini { int cri_alg; /* Algorithm to use */ - int cri_klen; /* Key length, in bits */ - int cri_rnd; /* Algorithm rounds, where relevant */ + u_int32_t cri_klen; /* Key length, in bits */ + u_int32_t cri_rnd; /* Algorithm rounds, where relevant */ char *cri_key; /* key to use */ u_int8_t cri_iv[EALG_MAX_BLOCK_LEN]; /* IV to use */ struct cryptoini *cri_next; @@ -432,9 +432,9 @@ struct cryptoini { /* Describe boundaries of a single crypto operation */ struct cryptodesc { - int crd_skip; /* How many bytes to ignore from start */ - int crd_len; /* How many bytes to process */ - int crd_inject; /* Where to inject results, if applicable */ + u_int32_t crd_skip; /* How many bytes to ignore from start */ + u_int32_t crd_len; /* How many bytes to process */ + u_int32_t crd_inject; /* Where to inject results, if applicable */ int crd_flags; #define CRD_F_ENCRYPT 0x01 /* Set when doing encryption */ @@ -454,13 +454,20 @@ struct cryptodesc { struct cryptodesc *crd_next; }; +struct cryptop_data { + struct csession *cse; + struct iovec iovec[1]; /* user requests never have more */ + struct uio uio; + size_t iov_len; +}; + /* Structure describing complete operation */ struct cryptop { TAILQ_ENTRY(cryptop) crp_next; u_int64_t crp_sid; /* Session ID */ - int crp_ilen; /* Input data total length */ - int crp_olen; /* Result total length */ + u_int32_t crp_ilen; /* Input data total length */ + u_int32_t crp_olen; /* Result total length */ int crp_etype; /* * Error type (zero means no error). @@ -512,13 +519,12 @@ struct cryptop { struct fcrypt *fcrp; void * dst; void * mac; - u_int len; + u_int32_t len; u_char tmp_iv[EALG_MAX_BLOCK_LEN]; u_char tmp_mac[CRYPTO_MAX_MAC_LEN]; - struct iovec iovec[1]; - struct uio uio; - uint32_t magic; + struct cryptop_data cod; + u_int32_t magic; struct cpu_info *reqcpu; /* * save requested CPU to do cryptoret * softint in the same CPU. @@ -543,11 +549,12 @@ struct cryptkop { u_int32_t krp_reqid; /* request id */ void * krp_usropaque; /* Opaque pointer from user, passed along */ - u_int krp_op; /* ie. CRK_MOD_EXP or other */ - u_int krp_status; /* return status */ - u_short krp_iparams; /* # of input parameters */ - u_short krp_oparams; /* # of output parameters */ + u_int32_t krp_op; /* ie. CRK_MOD_EXP or other */ + u_int32_t krp_status; /* return status */ + u_int16_t krp_iparams; /* # of input parameters */ + u_int16_t krp_oparams; /* # of output parameters */ u_int32_t krp_hid; + kmutex_t krp_lock; struct crparam krp_param[CRK_MAXPARAM]; /* kvm */ void (*krp_callback)(struct cryptkop *); /* * Callback function. Index: cryptodev_internal.h =================================================================== RCS file: /cvsroot/src/sys/opencrypto/cryptodev_internal.h,v retrieving revision 1.3 diff -u -p -u -r1.3 cryptodev_internal.h --- cryptodev_internal.h 2 Jun 2017 09:46:57 -0000 1.3 +++ cryptodev_internal.h 24 Apr 2026 22:19:50 -0000 @@ -6,7 +6,8 @@ extern kmutex_t cryptodev_mtx; struct csession; int cryptodev_op(struct csession *, struct crypt_op *, struct lwp *); -int cryptodev_mop(struct fcrypt *, struct crypt_n_op *, int, struct lwp *); +int cryptodev_mop(struct fcrypt *, struct crypt_n_op *, size_t, struct lwp *); int cryptodev_session(struct fcrypt *, struct session_op *); -int cryptodev_msession(struct fcrypt *, struct session_n_op *, int); -struct csession *cryptodev_csefind(struct fcrypt *fcr, u_int ses); +int cryptodev_msession(struct fcrypt *, struct session_n_op *, size_t); +void cryptodev_cse_free(struct csession *); +struct csession *cryptodev_cse_find(struct fcrypt *, uint32_t); Index: ocryptodev.c =================================================================== RCS file: /cvsroot/src/sys/opencrypto/ocryptodev.c,v retrieving revision 1.17 diff -u -p -u -r1.17 ocryptodev.c --- ocryptodev.c 12 Mar 2022 17:15:04 -0000 1.17 +++ ocryptodev.c 24 Apr 2026 22:19:50 -0000 @@ -154,15 +154,15 @@ mbail: kmem_free(osnop, osgop->count * sizeof(struct osession_n_op)); break; case OCIOCCRYPT: - mutex_enter(&cryptodev_mtx); ocop = (struct ocrypt_op *)data; - cse = cryptodev_csefind(fcr, ocop->ses); + cse = cryptodev_cse_find(fcr, ocop->ses); mutex_exit(&cryptodev_mtx); if (cse == NULL) { DPRINTF("csefind failed\n"); return EINVAL; } error = ocryptodev_op(cse, ocop, curlwp); + cryptodev_cse_free(cse); DPRINTF("ocryptodev_op error = %d\n", error); break; case OCIOCNCRYPTM: