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

Annotation of sys/crypto/crypto.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: crypto.c,v 1.48 2006/05/31 23:01:44 tedu Exp $        */
                      2: /*
                      3:  * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
                      4:  *
                      5:  * This code was written by Angelos D. Keromytis in Athens, Greece, in
                      6:  * February 2000. Network Security Technologies Inc. (NSTI) kindly
                      7:  * supported the development of this code.
                      8:  *
                      9:  * Copyright (c) 2000, 2001 Angelos D. Keromytis
                     10:  *
                     11:  * Permission to use, copy, and modify this software with or without fee
                     12:  * is hereby granted, provided that this entire notice is included in
                     13:  * all source code copies of any software which is or includes a copy or
                     14:  * modification of this software.
                     15:  *
                     16:  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
                     17:  * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
                     18:  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
                     19:  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
                     20:  * PURPOSE.
                     21:  */
                     22:
                     23: #include <sys/param.h>
                     24: #include <sys/systm.h>
                     25: #include <sys/malloc.h>
                     26: #include <sys/proc.h>
                     27: #include <sys/pool.h>
                     28: #include <crypto/cryptodev.h>
                     29:
                     30: struct cryptocap *crypto_drivers = NULL;
                     31: int crypto_drivers_num = 0;
                     32:
                     33: struct pool cryptop_pool;
                     34: struct pool cryptodesc_pool;
                     35: int crypto_pool_initialized = 0;
                     36:
                     37: struct cryptop *crp_req_queue = NULL;
                     38: struct cryptop **crp_req_queue_tail = NULL;
                     39:
                     40: struct cryptkop *krp_req_queue = NULL;
                     41: struct cryptkop **krp_req_queue_tail = NULL;
                     42:
                     43: /*
                     44:  * Create a new session.
                     45:  */
                     46: int
                     47: crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard)
                     48: {
                     49:        u_int32_t hid, lid, hid2 = -1;
                     50:        struct cryptocap *cpc;
                     51:        struct cryptoini *cr;
                     52:        int err, s, turn = 0;
                     53:
                     54:        if (crypto_drivers == NULL)
                     55:                return EINVAL;
                     56:
                     57:        s = splvm();
                     58:
                     59:        /*
                     60:         * The algorithm we use here is pretty stupid; just use the
                     61:         * first driver that supports all the algorithms we need. Do
                     62:         * a double-pass over all the drivers, ignoring software ones
                     63:         * at first, to deal with cases of drivers that register after
                     64:         * the software one(s) --- e.g., PCMCIA crypto cards.
                     65:         *
                     66:         * XXX We need more smarts here (in real life too, but that's
                     67:         * XXX another story altogether).
                     68:         */
                     69:        do {
                     70:                for (hid = 0; hid < crypto_drivers_num; hid++) {
                     71:                        cpc = &crypto_drivers[hid];
                     72:
                     73:                        /*
                     74:                         * If it's not initialized or has remaining sessions
                     75:                         * referencing it, skip.
                     76:                         */
                     77:                        if (cpc->cc_newsession == NULL ||
                     78:                            (cpc->cc_flags & CRYPTOCAP_F_CLEANUP))
                     79:                                continue;
                     80:
                     81:                        if (cpc->cc_flags & CRYPTOCAP_F_SOFTWARE) {
                     82:                                /*
                     83:                                 * First round of search, ignore
                     84:                                 * software drivers.
                     85:                                 */
                     86:                                if (turn == 0)
                     87:                                        continue;
                     88:                        } else { /* !CRYPTOCAP_F_SOFTWARE */
                     89:                                /* Second round of search, only software. */
                     90:                                if (turn == 1)
                     91:                                        continue;
                     92:                        }
                     93:
                     94:                        /* See if all the algorithms are supported. */
                     95:                        for (cr = cri; cr; cr = cr->cri_next) {
                     96:                                if (cpc->cc_alg[cr->cri_alg] == 0)
                     97:                                        break;
                     98:                        }
                     99:
                    100:                        /*
                    101:                         * If even one algorithm is not supported,
                    102:                         * keep searching.
                    103:                         */
                    104:                        if (cr != NULL)
                    105:                                continue;
                    106:
                    107:                        /*
                    108:                         * If we had a previous match, see how it compares
                    109:                         * to this one. Keep "remembering" whichever is
                    110:                         * the best of the two.
                    111:                         */
                    112:                        if (hid2 != -1) {
                    113:                                /*
                    114:                                 * Compare session numbers, pick the one
                    115:                                 * with the lowest.
                    116:                                 * XXX Need better metrics, this will
                    117:                                 * XXX just do un-weighted round-robin.
                    118:                                 */
                    119:                                if (crypto_drivers[hid].cc_sessions <=
                    120:                                    crypto_drivers[hid2].cc_sessions)
                    121:                                        hid2 = hid;
                    122:                        } else {
                    123:                                /*
                    124:                                 * Remember this one, for future
                    125:                                  * comparisons.
                    126:                                 */
                    127:                                hid2 = hid;
                    128:                        }
                    129:                }
                    130:
                    131:                /*
                    132:                 * If we found something worth remembering, leave. The
                    133:                 * side-effect is that we will always prefer a hardware
                    134:                 * driver over the software one.
                    135:                 */
                    136:                if (hid2 != -1)
                    137:                        break;
                    138:
                    139:                turn++;
                    140:
                    141:                /* If we only want hardware drivers, don't do second pass. */
                    142:        } while (turn <= 2 && hard == 0);
                    143:
                    144:        hid = hid2;
                    145:
                    146:        /*
                    147:         * Can't do everything in one session.
                    148:         *
                    149:         * XXX Fix this. We need to inject a "virtual" session
                    150:         * XXX layer right about here.
                    151:         */
                    152:
                    153:        if (hid == -1) {
                    154:                splx(s);
                    155:                return EINVAL;
                    156:        }
                    157:
                    158:        /* Call the driver initialization routine. */
                    159:        lid = hid; /* Pass the driver ID. */
                    160:        err = crypto_drivers[hid].cc_newsession(&lid, cri);
                    161:        if (err == 0) {
                    162:                (*sid) = hid;
                    163:                (*sid) <<= 32;
                    164:                (*sid) |= (lid & 0xffffffff);
                    165:                crypto_drivers[hid].cc_sessions++;
                    166:        }
                    167:
                    168:        splx(s);
                    169:        return err;
                    170: }
                    171:
                    172: /*
                    173:  * Delete an existing session (or a reserved session on an unregistered
                    174:  * driver).
                    175:  */
                    176: int
                    177: crypto_freesession(u_int64_t sid)
                    178: {
                    179:        int err = 0, s;
                    180:        u_int32_t hid;
                    181:
                    182:        if (crypto_drivers == NULL)
                    183:                return EINVAL;
                    184:
                    185:        /* Determine two IDs. */
                    186:        hid = (sid >> 32) & 0xffffffff;
                    187:
                    188:        if (hid >= crypto_drivers_num)
                    189:                return ENOENT;
                    190:
                    191:        s = splvm();
                    192:
                    193:        if (crypto_drivers[hid].cc_sessions)
                    194:                crypto_drivers[hid].cc_sessions--;
                    195:
                    196:        /* Call the driver cleanup routine, if available. */
                    197:        if (crypto_drivers[hid].cc_freesession)
                    198:                err = crypto_drivers[hid].cc_freesession(sid);
                    199:
                    200:        /*
                    201:         * If this was the last session of a driver marked as invalid,
                    202:         * make the entry available for reuse.
                    203:         */
                    204:        if ((crypto_drivers[hid].cc_flags & CRYPTOCAP_F_CLEANUP) &&
                    205:            crypto_drivers[hid].cc_sessions == 0)
                    206:                bzero(&crypto_drivers[hid], sizeof(struct cryptocap));
                    207:
                    208:        splx(s);
                    209:        return err;
                    210: }
                    211:
                    212: /*
                    213:  * Find an empty slot.
                    214:  */
                    215: int32_t
                    216: crypto_get_driverid(u_int8_t flags)
                    217: {
                    218:        struct cryptocap *newdrv;
                    219:        int i, s;
                    220:
                    221:        s = splvm();
                    222:
                    223:        if (crypto_drivers_num == 0) {
                    224:                crypto_drivers_num = CRYPTO_DRIVERS_INITIAL;
                    225:                crypto_drivers = malloc(crypto_drivers_num *
                    226:                    sizeof(struct cryptocap), M_CRYPTO_DATA, M_NOWAIT);
                    227:                if (crypto_drivers == NULL) {
                    228:                        crypto_drivers_num = 0;
                    229:                        splx(s);
                    230:                        return -1;
                    231:                }
                    232:
                    233:                bzero(crypto_drivers, crypto_drivers_num *
                    234:                    sizeof(struct cryptocap));
                    235:        }
                    236:
                    237:        for (i = 0; i < crypto_drivers_num; i++) {
                    238:                if (crypto_drivers[i].cc_process == NULL &&
                    239:                    !(crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP) &&
                    240:                    crypto_drivers[i].cc_sessions == 0) {
                    241:                        crypto_drivers[i].cc_sessions = 1; /* Mark */
                    242:                        crypto_drivers[i].cc_flags = flags;
                    243:                        splx(s);
                    244:                        return i;
                    245:                }
                    246:        }
                    247:
                    248:        /* Out of entries, allocate some more. */
                    249:        if (i == crypto_drivers_num) {
                    250:                /* Be careful about wrap-around. */
                    251:                if (2 * crypto_drivers_num <= crypto_drivers_num) {
                    252:                        splx(s);
                    253:                        return -1;
                    254:                }
                    255:
                    256:                newdrv = malloc(2 * crypto_drivers_num *
                    257:                    sizeof(struct cryptocap), M_CRYPTO_DATA, M_NOWAIT);
                    258:                if (newdrv == NULL) {
                    259:                        splx(s);
                    260:                        return -1;
                    261:                }
                    262:
                    263:                bcopy(crypto_drivers, newdrv,
                    264:                    crypto_drivers_num * sizeof(struct cryptocap));
                    265:                bzero(&newdrv[crypto_drivers_num],
                    266:                    crypto_drivers_num * sizeof(struct cryptocap));
                    267:
                    268:                newdrv[i].cc_sessions = 1; /* Mark */
                    269:                newdrv[i].cc_flags = flags;
                    270:                crypto_drivers_num *= 2;
                    271:
                    272:                free(crypto_drivers, M_CRYPTO_DATA);
                    273:                crypto_drivers = newdrv;
                    274:                splx(s);
                    275:                return i;
                    276:        }
                    277:
                    278:        /* Shouldn't really get here... */
                    279:        splx(s);
                    280:        return -1;
                    281: }
                    282:
                    283: /*
                    284:  * Register a crypto driver. It should be called once for each algorithm
                    285:  * supported by the driver.
                    286:  */
                    287: int
                    288: crypto_kregister(u_int32_t driverid, int *kalg,
                    289:     int (*kprocess)(struct cryptkop *))
                    290: {
                    291:        int s, i;
                    292:
                    293:        if (driverid >= crypto_drivers_num || kalg  == NULL ||
                    294:            crypto_drivers == NULL)
                    295:                return EINVAL;
                    296:
                    297:        s = splvm();
                    298:
                    299:        for (i = 0; i < CRK_ALGORITHM_MAX; i++) {
                    300:                /*
                    301:                 * XXX Do some performance testing to determine
                    302:                 * placing.  We probably need an auxiliary data
                    303:                 * structure that describes relative performances.
                    304:                 */
                    305:
                    306:                crypto_drivers[driverid].cc_kalg[i] = kalg[i];
                    307:        }
                    308:
                    309:        crypto_drivers[driverid].cc_kprocess = kprocess;
                    310:
                    311:        splx(s);
                    312:        return 0;
                    313: }
                    314:
                    315: /* Register a crypto driver. */
                    316: int
                    317: crypto_register(u_int32_t driverid, int *alg,
                    318:     int (*newses)(u_int32_t *, struct cryptoini *),
                    319:     int (*freeses)(u_int64_t), int (*process)(struct cryptop *))
                    320: {
                    321:        int s, i;
                    322:
                    323:
                    324:        if (driverid >= crypto_drivers_num || alg == NULL ||
                    325:            crypto_drivers == NULL)
                    326:                return EINVAL;
                    327:
                    328:        s = splvm();
                    329:
                    330:        for (i = 0; i < CRYPTO_ALGORITHM_ALL; i++) {
                    331:                /*
                    332:                 * XXX Do some performance testing to determine
                    333:                 * placing.  We probably need an auxiliary data
                    334:                 * structure that describes relative performances.
                    335:                 */
                    336:
                    337:                crypto_drivers[driverid].cc_alg[i] = alg[i];
                    338:        }
                    339:
                    340:
                    341:        crypto_drivers[driverid].cc_newsession = newses;
                    342:        crypto_drivers[driverid].cc_process = process;
                    343:        crypto_drivers[driverid].cc_freesession = freeses;
                    344:        crypto_drivers[driverid].cc_sessions = 0; /* Unmark */
                    345:
                    346:        splx(s);
                    347:
                    348:        return 0;
                    349: }
                    350:
                    351: /*
                    352:  * Unregister a crypto driver. If there are pending sessions using it,
                    353:  * leave enough information around so that subsequent calls using those
                    354:  * sessions will correctly detect the driver being unregistered and reroute
                    355:  * the request.
                    356:  */
                    357: int
                    358: crypto_unregister(u_int32_t driverid, int alg)
                    359: {
                    360:        int i = CRYPTO_ALGORITHM_MAX + 1, s;
                    361:        u_int32_t ses;
                    362:
                    363:        s = splvm();
                    364:
                    365:        /* Sanity checks. */
                    366:        if (driverid >= crypto_drivers_num || crypto_drivers == NULL ||
                    367:            ((alg <= 0 || alg > CRYPTO_ALGORITHM_MAX) &&
                    368:                alg != CRYPTO_ALGORITHM_ALL) ||
                    369:            crypto_drivers[driverid].cc_alg[alg] == 0) {
                    370:                splx(s);
                    371:                return EINVAL;
                    372:        }
                    373:
                    374:        if (alg != CRYPTO_ALGORITHM_ALL) {
                    375:                crypto_drivers[driverid].cc_alg[alg] = 0;
                    376:
                    377:                /* Was this the last algorithm ? */
                    378:                for (i = 1; i <= CRYPTO_ALGORITHM_MAX; i++)
                    379:                        if (crypto_drivers[driverid].cc_alg[i] != 0)
                    380:                                break;
                    381:        }
                    382:
                    383:        /*
                    384:         * If a driver unregistered its last algorithm or all of them
                    385:         * (alg == CRYPTO_ALGORITHM_ALL), cleanup its entry.
                    386:         */
                    387:        if (i == CRYPTO_ALGORITHM_MAX + 1 || alg == CRYPTO_ALGORITHM_ALL) {
                    388:                ses = crypto_drivers[driverid].cc_sessions;
                    389:                bzero(&crypto_drivers[driverid], sizeof(struct cryptocap));
                    390:                if (ses != 0) {
                    391:                        /*
                    392:                         * If there are pending sessions, just mark as invalid.
                    393:                         */
                    394:                        crypto_drivers[driverid].cc_flags |= CRYPTOCAP_F_CLEANUP;
                    395:                        crypto_drivers[driverid].cc_sessions = ses;
                    396:                }
                    397:        }
                    398:        splx(s);
                    399:        return 0;
                    400: }
                    401:
                    402: /*
                    403:  * Add crypto request to a queue, to be processed by a kernel thread.
                    404:  */
                    405: int
                    406: crypto_dispatch(struct cryptop *crp)
                    407: {
                    408:        int s;
                    409:        u_int32_t hid;
                    410:
                    411:        s = splvm();
                    412:        /*
                    413:         * Keep track of ops per driver, for coallescing purposes. If
                    414:         * we have been given an invalid hid, we'll deal with in the
                    415:         * crypto_invoke(), through session migration.
                    416:         */
                    417:        hid = (crp->crp_sid >> 32) & 0xffffffff;
                    418:        if (hid < crypto_drivers_num)
                    419:                crypto_drivers[hid].cc_queued++;
                    420:
                    421:        crp->crp_next = NULL;
                    422:        if (crp_req_queue == NULL) {
                    423:                crp_req_queue = crp;
                    424:                crp_req_queue_tail = &(crp->crp_next);
                    425:                splx(s);
                    426:                wakeup(&crp_req_queue); /* Shared wait channel. */
                    427:        } else {
                    428:                *crp_req_queue_tail = crp;
                    429:                crp_req_queue_tail = &(crp->crp_next);
                    430:                splx(s);
                    431:        }
                    432:        return 0;
                    433: }
                    434:
                    435: int
                    436: crypto_kdispatch(struct cryptkop *krp)
                    437: {
                    438:        int s;
                    439:
                    440:        s = splvm();
                    441:
                    442:        krp->krp_next = NULL;
                    443:        if (krp_req_queue == NULL) {
                    444:                krp_req_queue = krp;
                    445:                krp_req_queue_tail = &(krp->krp_next);
                    446:                splx(s);
                    447:                wakeup(&crp_req_queue); /* Shared wait channel. */
                    448:        } else {
                    449:                *krp_req_queue_tail = krp;
                    450:                krp_req_queue_tail = &(krp->krp_next);
                    451:                splx(s);
                    452:        }
                    453:        return 0;
                    454: }
                    455:
                    456: /*
                    457:  * Dispatch an asymmetric crypto request to the appropriate crypto devices.
                    458:  */
                    459: int
                    460: crypto_kinvoke(struct cryptkop *krp)
                    461: {
                    462:        extern int cryptodevallowsoft;
                    463:        u_int32_t hid;
                    464:        int error;
                    465:
                    466:        /* Sanity checks. */
                    467:        if (krp == NULL || krp->krp_callback == NULL)
                    468:                return (EINVAL);
                    469:
                    470:        for (hid = 0; hid < crypto_drivers_num; hid++) {
                    471:                if ((crypto_drivers[hid].cc_flags & CRYPTOCAP_F_SOFTWARE) &&
                    472:                    cryptodevallowsoft == 0)
                    473:                        continue;
                    474:                if (crypto_drivers[hid].cc_kprocess == NULL)
                    475:                        continue;
                    476:                if ((crypto_drivers[hid].cc_kalg[krp->krp_op] &
                    477:                    CRYPTO_ALG_FLAG_SUPPORTED) == 0)
                    478:                        continue;
                    479:                break;
                    480:        }
                    481:
                    482:        if (hid == crypto_drivers_num) {
                    483:                krp->krp_status = ENODEV;
                    484:                crypto_kdone(krp);
                    485:                return (0);
                    486:        }
                    487:
                    488:        krp->krp_hid = hid;
                    489:
                    490:        crypto_drivers[hid].cc_koperations++;
                    491:
                    492:        error = crypto_drivers[hid].cc_kprocess(krp);
                    493:        if (error) {
                    494:                krp->krp_status = error;
                    495:                crypto_kdone(krp);
                    496:        }
                    497:        return (0);
                    498: }
                    499:
                    500: /*
                    501:  * Dispatch a crypto request to the appropriate crypto devices.
                    502:  */
                    503: int
                    504: crypto_invoke(struct cryptop *crp)
                    505: {
                    506:        struct cryptodesc *crd;
                    507:        u_int64_t nid;
                    508:        u_int32_t hid;
                    509:        int error;
                    510:
                    511:        /* Sanity checks. */
                    512:        if (crp == NULL || crp->crp_callback == NULL)
                    513:                return EINVAL;
                    514:
                    515:        if (crp->crp_desc == NULL || crypto_drivers == NULL) {
                    516:                crp->crp_etype = EINVAL;
                    517:                crypto_done(crp);
                    518:                return 0;
                    519:        }
                    520:
                    521:        hid = (crp->crp_sid >> 32) & 0xffffffff;
                    522:        if (hid >= crypto_drivers_num)
                    523:                goto migrate;
                    524:
                    525:        crypto_drivers[hid].cc_queued--;
                    526:
                    527:        if (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_CLEANUP) {
                    528:                crypto_freesession(crp->crp_sid);
                    529:                goto migrate;
                    530:        }
                    531:
                    532:        if (crypto_drivers[hid].cc_process == NULL)
                    533:                goto migrate;
                    534:
                    535:        crypto_drivers[hid].cc_operations++;
                    536:        crypto_drivers[hid].cc_bytes += crp->crp_ilen;
                    537:
                    538:        error = crypto_drivers[hid].cc_process(crp);
                    539:        if (error) {
                    540:                if (error == ERESTART) {
                    541:                        /* Unregister driver and migrate session. */
                    542:                        crypto_unregister(hid, CRYPTO_ALGORITHM_ALL);
                    543:                        goto migrate;
                    544:                } else {
                    545:                        crp->crp_etype = error;
                    546:                        crypto_done(crp);
                    547:                }
                    548:        }
                    549:
                    550:        return 0;
                    551:
                    552:  migrate:
                    553:        /* Migrate session. */
                    554:        for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next)
                    555:                crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI);
                    556:
                    557:        if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI), 0) == 0)
                    558:                crp->crp_sid = nid;
                    559:
                    560:        crp->crp_etype = EAGAIN;
                    561:        crypto_done(crp);
                    562:        return 0;
                    563: }
                    564:
                    565: /*
                    566:  * Release a set of crypto descriptors.
                    567:  */
                    568: void
                    569: crypto_freereq(struct cryptop *crp)
                    570: {
                    571:        struct cryptodesc *crd;
                    572:        int s;
                    573:
                    574:        if (crp == NULL)
                    575:                return;
                    576:
                    577:        s = splvm();
                    578:
                    579:        while ((crd = crp->crp_desc) != NULL) {
                    580:                crp->crp_desc = crd->crd_next;
                    581:                pool_put(&cryptodesc_pool, crd);
                    582:        }
                    583:
                    584:        pool_put(&cryptop_pool, crp);
                    585:        splx(s);
                    586: }
                    587:
                    588: /*
                    589:  * Acquire a set of crypto descriptors.
                    590:  */
                    591: struct cryptop *
                    592: crypto_getreq(int num)
                    593: {
                    594:        struct cryptodesc *crd;
                    595:        struct cryptop *crp;
                    596:        int s;
                    597:
                    598:        s = splvm();
                    599:
                    600:        if (crypto_pool_initialized == 0) {
                    601:                pool_init(&cryptop_pool, sizeof(struct cryptop), 0, 0,
                    602:                    0, "cryptop", NULL);
                    603:                pool_init(&cryptodesc_pool, sizeof(struct cryptodesc), 0, 0,
                    604:                    0, "cryptodesc", NULL);
                    605:                crypto_pool_initialized = 1;
                    606:        }
                    607:
                    608:        crp = pool_get(&cryptop_pool, PR_NOWAIT);
                    609:        if (crp == NULL) {
                    610:                splx(s);
                    611:                return NULL;
                    612:        }
                    613:        bzero(crp, sizeof(struct cryptop));
                    614:
                    615:        while (num--) {
                    616:                crd = pool_get(&cryptodesc_pool, PR_NOWAIT);
                    617:                if (crd == NULL) {
                    618:                        splx(s);
                    619:                        crypto_freereq(crp);
                    620:                        return NULL;
                    621:                }
                    622:
                    623:                bzero(crd, sizeof(struct cryptodesc));
                    624:                crd->crd_next = crp->crp_desc;
                    625:                crp->crp_desc = crd;
                    626:        }
                    627:
                    628:        splx(s);
                    629:        return crp;
                    630: }
                    631:
                    632: /*
                    633:  * Crypto thread, runs as a kernel thread to process crypto requests.
                    634:  */
                    635: void
                    636: crypto_thread(void)
                    637: {
                    638:        struct cryptop *crp;
                    639:        struct cryptkop *krp;
                    640:        int s;
                    641:
                    642:        s = splvm();
                    643:
                    644:        for (;;) {
                    645:                crp = crp_req_queue;
                    646:                krp = krp_req_queue;
                    647:                if (crp == NULL && krp == NULL) {
                    648:                        (void)tsleep(&crp_req_queue, PLOCK, "crypto_wait", 0);
                    649:                        continue;
                    650:                }
                    651:
                    652:                if (crp) {
                    653:                        /* Remove from the queue. */
                    654:                        crp_req_queue = crp->crp_next;
                    655:                        crypto_invoke(crp);
                    656:                }
                    657:                if (krp) {
                    658:                        /* Remove from the queue. */
                    659:                        krp_req_queue = krp->krp_next;
                    660:                        crypto_kinvoke(krp);
                    661:                }
                    662:        }
                    663: }
                    664:
                    665: /*
                    666:  * Invoke the callback on behalf of the driver.
                    667:  */
                    668: void
                    669: crypto_done(struct cryptop *crp)
                    670: {
                    671:        crp->crp_flags |= CRYPTO_F_DONE;
                    672:        crp->crp_callback(crp);
                    673: }
                    674:
                    675: /*
                    676:  * Invoke the callback on behalf of the driver.
                    677:  */
                    678: void
                    679: crypto_kdone(struct cryptkop *krp)
                    680: {
                    681:        krp->krp_callback(krp);
                    682: }
                    683:
                    684: int
                    685: crypto_getfeat(int *featp)
                    686: {
                    687:        extern int cryptodevallowsoft, userasymcrypto;
                    688:        int hid, kalg, feat = 0;
                    689:
                    690:        if (userasymcrypto == 0)
                    691:                goto out;
                    692:        for (hid = 0; hid < crypto_drivers_num; hid++) {
                    693:                if ((crypto_drivers[hid].cc_flags & CRYPTOCAP_F_SOFTWARE) &&
                    694:                    cryptodevallowsoft == 0) {
                    695:                        continue;
                    696:                }
                    697:                if (crypto_drivers[hid].cc_kprocess == NULL)
                    698:                        continue;
                    699:                for (kalg = 0; kalg < CRK_ALGORITHM_MAX; kalg++)
                    700:                        if ((crypto_drivers[hid].cc_kalg[kalg] &
                    701:                            CRYPTO_ALG_FLAG_SUPPORTED) != 0)
                    702:                                feat |=  1 << kalg;
                    703:        }
                    704: out:
                    705:        *featp = feat;
                    706:        return (0);
                    707: }

CVSweb