[BACK]Return to cryptodev.c CVS log [TXT][DIR] Up to [local] / sys / crypto

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