diff options
Diffstat (limited to 'sys/crypto/crypto.c')
-rw-r--r-- | sys/crypto/crypto.c | 610 |
1 files changed, 290 insertions, 320 deletions
diff --git a/sys/crypto/crypto.c b/sys/crypto/crypto.c index 6957f799d19..203dc6688f0 100644 --- a/sys/crypto/crypto.c +++ b/sys/crypto/crypto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: crypto.c,v 1.18 2001/06/06 18:58:52 angelos Exp $ */ +/* $OpenBSD: crypto.c,v 1.19 2001/06/16 22:17:49 deraadt Exp $ */ /* * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu) @@ -44,74 +44,71 @@ struct cryptop **crp_req_queue_tail = NULL; int crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard) { - struct cryptoini *cr; - u_int32_t hid, lid; - int err, s; + struct cryptoini *cr; + u_int32_t hid, lid; + int err, s; - if (crypto_drivers == NULL) - return EINVAL; + if (crypto_drivers == NULL) + return EINVAL; - s = splimp(); + s = splimp(); - /* - * The algorithm we use here is pretty stupid; just use the - * first driver that supports all the algorithms we need. - * - * XXX We need more smarts here (in real life too, but that's - * XXX another story altogether). - */ + /* + * The algorithm we use here is pretty stupid; just use the + * first driver that supports all the algorithms we need. + * + * XXX We need more smarts here (in real life too, but that's + * XXX another story altogether). + */ + + for (hid = 0; hid < crypto_drivers_num; hid++) { + /* + * If it's not initialized or has remaining sessions referencing + * it, skip. + */ + if (crypto_drivers[hid].cc_newsession == NULL || + (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_CLEANUP)) + continue; + + /* hardware requested -- ignore software drivers */ + if (hard && + (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_SOFTWARE)) + continue; + + /* See if all the algorithms are supported */ + for (cr = cri; cr; cr = cr->cri_next) + if (crypto_drivers[hid].cc_alg[cr->cri_alg] == 0) + break; + + /* Ok, all algorithms are supported */ + if (cr == NULL) + break; + } - for (hid = 0; hid < crypto_drivers_num; hid++) - { /* - * If it's not initialized or has remaining sessions referencing - * it, skip. - */ - if ((crypto_drivers[hid].cc_newsession == NULL) || - (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_CLEANUP)) - continue; - - /* hardware requested -- ignore software drivers */ - if (hard && - (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_SOFTWARE)) - continue; - - /* See if all the algorithms are supported */ - for (cr = cri; cr; cr = cr->cri_next) - if (crypto_drivers[hid].cc_alg[cr->cri_alg] == 0) - break; - - /* Ok, all algorithms are supported */ - if (cr == NULL) - break; - } - - /* - * Can't do everything in one session. - * - * XXX Fix this. We need to inject a "virtual" session layer right - * XXX about here. - */ - - if (hid == crypto_drivers_num) - { + * Can't do everything in one session. + * + * XXX Fix this. We need to inject a "virtual" session layer right + * XXX about here. + */ + + if (hid == crypto_drivers_num) { + splx(s); + return EINVAL; + } + + /* Call the driver initialization routine */ + lid = hid; /* Pass the driver ID */ + err = crypto_drivers[hid].cc_newsession(&lid, cri); + if (err == 0) { + (*sid) = hid; + (*sid) <<= 32; + (*sid) |= (lid & 0xffffffff); + crypto_drivers[hid].cc_sessions++; + } + splx(s); - return EINVAL; - } - - /* Call the driver initialization routine */ - lid = hid; /* Pass the driver ID */ - err = crypto_drivers[hid].cc_newsession(&lid, cri); - if (err == 0) - { - (*sid) = hid; - (*sid) <<= 32; - (*sid) |= (lid & 0xffffffff); - crypto_drivers[hid].cc_sessions++; - } - - splx(s); - return err; + return err; } /* @@ -121,37 +118,37 @@ crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard) int crypto_freesession(u_int64_t sid) { - int err = 0, s; - u_int32_t hid; + int err = 0, s; + u_int32_t hid; - if (crypto_drivers == NULL) - return EINVAL; + if (crypto_drivers == NULL) + return EINVAL; - /* Determine two IDs */ - hid = (sid >> 32) & 0xffffffff; + /* Determine two IDs */ + hid = (sid >> 32) & 0xffffffff; - if (hid >= crypto_drivers_num) - return ENOENT; + if (hid >= crypto_drivers_num) + return ENOENT; - s = splimp(); + s = splimp(); - if (crypto_drivers[hid].cc_sessions) - crypto_drivers[hid].cc_sessions--; + if (crypto_drivers[hid].cc_sessions) + crypto_drivers[hid].cc_sessions--; - /* Call the driver cleanup routine, if available */ - if (crypto_drivers[hid].cc_freesession) - err = crypto_drivers[hid].cc_freesession(sid); + /* Call the driver cleanup routine, if available */ + if (crypto_drivers[hid].cc_freesession) + err = crypto_drivers[hid].cc_freesession(sid); - /* - * If this was the last session of a driver marked as invalid, make - * the entry available for reuse. - */ - if ((crypto_drivers[hid].cc_flags & CRYPTOCAP_F_CLEANUP) && - (crypto_drivers[hid].cc_sessions == 0)) - bzero(&crypto_drivers[hid], sizeof(struct cryptocap)); + /* + * If this was the last session of a driver marked as invalid, + * make the entry available for reuse. + */ + if ((crypto_drivers[hid].cc_flags & CRYPTOCAP_F_CLEANUP) && + crypto_drivers[hid].cc_sessions == 0) + bzero(&crypto_drivers[hid], sizeof(struct cryptocap)); - splx(s); - return err; + splx(s); + return err; } /* @@ -160,69 +157,65 @@ crypto_freesession(u_int64_t sid) int32_t crypto_get_driverid(void) { - struct cryptocap *newdrv; - int i, s = splimp(); - - if (crypto_drivers_num == 0) - { - crypto_drivers_num = CRYPTO_DRIVERS_INITIAL; - crypto_drivers = malloc(crypto_drivers_num * sizeof(struct cryptocap), - M_CRYPTO_DATA, M_NOWAIT); - if (crypto_drivers == NULL) - { - splx(s); - crypto_drivers_num = 0; - return -1; + struct cryptocap *newdrv; + int i, s = splimp(); + + if (crypto_drivers_num == 0) { + crypto_drivers_num = CRYPTO_DRIVERS_INITIAL; + crypto_drivers = malloc(crypto_drivers_num * + sizeof(struct cryptocap), M_CRYPTO_DATA, M_NOWAIT); + if (crypto_drivers == NULL) { + splx(s); + crypto_drivers_num = 0; + return -1; + } + + bzero(crypto_drivers, crypto_drivers_num * + sizeof(struct cryptocap)); } - bzero(crypto_drivers, crypto_drivers_num * sizeof(struct cryptocap)); - } - - for (i = 0; i < crypto_drivers_num; i++) - if ((crypto_drivers[i].cc_process == NULL) && - !(crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP) && - (crypto_drivers[i].cc_sessions == 0)) - { - crypto_drivers[i].cc_sessions = 1; /* Mark */ - splx(s); - return i; - } - - /* Out of entries, allocate some more */ - if (i == crypto_drivers_num) - { - /* Be careful about wrap-around */ - if (2 * crypto_drivers_num <= crypto_drivers_num) - { - splx(s); - return -1; + for (i = 0; i < crypto_drivers_num; i++) { + if (crypto_drivers[i].cc_process == NULL && + !(crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP) && + crypto_drivers[i].cc_sessions == 0) { + crypto_drivers[i].cc_sessions = 1; /* Mark */ + splx(s); + return i; + } } - newdrv = malloc(2 * crypto_drivers_num * sizeof(struct cryptocap), - M_CRYPTO_DATA, M_NOWAIT); - if (newdrv == NULL) - { - splx(s); - return -1; + /* Out of entries, allocate some more */ + if (i == crypto_drivers_num) { + /* Be careful about wrap-around */ + if (2 * crypto_drivers_num <= crypto_drivers_num) { + splx(s); + return -1; + } + + newdrv = malloc(2 * crypto_drivers_num * sizeof(struct cryptocap), + M_CRYPTO_DATA, M_NOWAIT); + if (newdrv == NULL) { + splx(s); + return -1; + } + + bcopy(crypto_drivers, newdrv, + crypto_drivers_num * sizeof(struct cryptocap)); + bzero(&newdrv[crypto_drivers_num], + crypto_drivers_num * sizeof(struct cryptocap)); + + newdrv[i].cc_sessions = 1; /* Mark */ + crypto_drivers_num *= 2; + + free(crypto_drivers, M_CRYPTO_DATA); + crypto_drivers = newdrv; + splx(s); + return i; } - bcopy(crypto_drivers, newdrv, - crypto_drivers_num * sizeof(struct cryptocap)); - bzero(&newdrv[crypto_drivers_num], - crypto_drivers_num * sizeof(struct cryptocap)); - - newdrv[i].cc_sessions = 1; /* Mark */ - crypto_drivers_num *= 2; - - free(crypto_drivers, M_CRYPTO_DATA); - crypto_drivers = newdrv; + /* Shouldn't really get here... */ splx(s); - return i; - } - - /* Shouldn't really get here... */ - splx(s); - return -1; + return -1; } /* @@ -234,32 +227,31 @@ crypto_register(u_int32_t driverid, int alg, int (*newses)(u_int32_t *, struct cryptoini *), int (*freeses)(u_int64_t), int (*process)(struct cryptop *)) { - int s; - - if ((driverid >= crypto_drivers_num) || (alg <= 0) || - (alg > CRYPTO_ALGORITHM_MAX) || (crypto_drivers == NULL)) - return EINVAL; + int s; - s = splimp(); + if (driverid >= crypto_drivers_num || alg <= 0 || + alg > CRYPTO_ALGORITHM_MAX || crypto_drivers == NULL) + return EINVAL; - /* - * XXX Do some performance testing to determine placing. - * XXX We probably need an auxiliary data structure that describes - * XXX relative performances. - */ + s = splimp(); - crypto_drivers[driverid].cc_alg[alg] = 1; - - if (crypto_drivers[driverid].cc_process == NULL) - { - crypto_drivers[driverid].cc_newsession = newses; - crypto_drivers[driverid].cc_process = process; - crypto_drivers[driverid].cc_freesession = freeses; - crypto_drivers[driverid].cc_sessions = 0; /* Unmark */ - } + /* + * XXX Do some performance testing to determine placing. + * XXX We probably need an auxiliary data structure that describes + * XXX relative performances. + */ + + crypto_drivers[driverid].cc_alg[alg] = 1; + + if (crypto_drivers[driverid].cc_process == NULL) { + crypto_drivers[driverid].cc_newsession = newses; + crypto_drivers[driverid].cc_process = process; + crypto_drivers[driverid].cc_freesession = freeses; + crypto_drivers[driverid].cc_sessions = 0; /* Unmark */ + } - splx(s); - return 0; + splx(s); + return 0; } /* @@ -271,40 +263,35 @@ crypto_register(u_int32_t driverid, int alg, int crypto_unregister(u_int32_t driverid, int alg) { - int i, s = splimp(); - u_int32_t ses; - - /* Sanity checks */ - if ((driverid >= crypto_drivers_num) || (alg <= 0) || - (alg > CRYPTO_ALGORITHM_MAX) || (crypto_drivers == NULL) || - (crypto_drivers[driverid].cc_alg[alg] == 0)) - { - splx(s); - return EINVAL; - } - - crypto_drivers[driverid].cc_alg[alg] = 0; - - /* Was this the last algorithm ? */ - for (i = 1; i <= CRYPTO_ALGORITHM_MAX; i++) - if (crypto_drivers[driverid].cc_alg[i] != 0) - break; - - if (i == CRYPTO_ALGORITHM_MAX + 1) - { - ses = crypto_drivers[driverid].cc_sessions; - bzero(&crypto_drivers[driverid], sizeof(struct cryptocap)); - - if (ses != 0) - { - /* If there are pending sessions, just mark as invalid */ - crypto_drivers[driverid].cc_flags |= CRYPTOCAP_F_CLEANUP; - crypto_drivers[driverid].cc_sessions = ses; + int i, s = splimp(); + u_int32_t ses; + + /* Sanity checks */ + if (driverid >= crypto_drivers_num || alg <= 0 || + alg > CRYPTO_ALGORITHM_MAX || crypto_drivers == NULL || + crypto_drivers[driverid].cc_alg[alg] == 0) { + splx(s); + return EINVAL; } - } - splx(s); - return 0; + crypto_drivers[driverid].cc_alg[alg] = 0; + + /* Was this the last algorithm ? */ + for (i = 1; i <= CRYPTO_ALGORITHM_MAX; i++) + if (crypto_drivers[driverid].cc_alg[i] != 0) + break; + + if (i == CRYPTO_ALGORITHM_MAX + 1) { + ses = crypto_drivers[driverid].cc_sessions; + bzero(&crypto_drivers[driverid], sizeof(struct cryptocap)); + if (ses != 0) { + /* If there are pending sessions, just mark as invalid */ + crypto_drivers[driverid].cc_flags |= CRYPTOCAP_F_CLEANUP; + crypto_drivers[driverid].cc_sessions = ses; + } + } + splx(s); + return 0; } /* @@ -313,22 +300,19 @@ crypto_unregister(u_int32_t driverid, int alg) int crypto_dispatch(struct cryptop *crp) { - int s = splimp(); - - if (crp_req_queue == NULL) { - crp_req_queue = crp; - crp_req_queue_tail = &(crp->crp_next); - splx(s); - - wakeup((caddr_t) &crp_req_queue); - } - else - { - *crp_req_queue_tail = crp; - crp_req_queue_tail = &(crp->crp_next); - splx(s); - } - return 0; + int s = splimp(); + + if (crp_req_queue == NULL) { + crp_req_queue = crp; + crp_req_queue_tail = &(crp->crp_next); + splx(s); + wakeup((caddr_t) &crp_req_queue); + } else { + *crp_req_queue_tail = crp; + crp_req_queue_tail = &(crp->crp_next); + splx(s); + } + return 0; } /* @@ -337,56 +321,52 @@ crypto_dispatch(struct cryptop *crp) int crypto_invoke(struct cryptop *crp) { - struct cryptodesc *crd; - u_int64_t nid; - u_int32_t hid; - - /* Sanity checks */ - if ((crp == NULL) || (crp->crp_callback == NULL)) - return EINVAL; - - if ((crp->crp_desc == NULL) || (crypto_drivers == NULL)) - { - crp->crp_etype = EINVAL; - crypto_done(crp); - return 0; - } + struct cryptodesc *crd; + u_int64_t nid; + u_int32_t hid; + + /* Sanity checks */ + if (crp == NULL || crp->crp_callback == NULL) + return EINVAL; + + if (crp->crp_desc == NULL || crypto_drivers == NULL) { + crp->crp_etype = EINVAL; + crypto_done(crp); + return 0; + } - hid = (crp->crp_sid >> 32) & 0xffffffff; + hid = (crp->crp_sid >> 32) & 0xffffffff; + if (hid >= crypto_drivers_num) { + /* Migrate session */ + for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next) + crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI); - if (hid >= crypto_drivers_num) - { - /* Migrate session */ - for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next) - crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI); + if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI), 0) == 0) + crp->crp_sid = nid; - if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI), 0) == 0) - crp->crp_sid = nid; + crp->crp_etype = EAGAIN; + crypto_done(crp); + return 0; + } - crp->crp_etype = EAGAIN; - crypto_done(crp); - return 0; - } + if (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_CLEANUP) + crypto_freesession(crp->crp_sid); - if (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_CLEANUP) - crypto_freesession(crp->crp_sid); + if (crypto_drivers[hid].cc_process == NULL) { + /* Migrate session */ + for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next) + crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI); - if (crypto_drivers[hid].cc_process == NULL) - { - /* Migrate session */ - for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next) - crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI); + if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI), 0) == 0) + crp->crp_sid = nid; - if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI), 0) == 0) - crp->crp_sid = nid; + crp->crp_etype = EAGAIN; + crypto_done(crp); + return 0; + } - crp->crp_etype = EAGAIN; - crypto_done(crp); + crypto_drivers[hid].cc_process(crp); return 0; - } - - crypto_drivers[hid].cc_process(crp); - return 0; } /* @@ -395,22 +375,21 @@ crypto_invoke(struct cryptop *crp) void crypto_freereq(struct cryptop *crp) { - struct cryptodesc *crd; - int s; + struct cryptodesc *crd; + int s; - if (crp == NULL) - return; + if (crp == NULL) + return; - s = splimp(); + s = splimp(); - while ((crd = crp->crp_desc) != NULL) - { - crp->crp_desc = crd->crd_next; - pool_put(&cryptodesc_pool, crd); - } + while ((crd = crp->crp_desc) != NULL) { + crp->crp_desc = crd->crd_next; + pool_put(&cryptodesc_pool, crd); + } - pool_put(&cryptop_pool, crp); - splx(s); + pool_put(&cryptop_pool, crp); + splx(s); } /* @@ -419,46 +398,40 @@ crypto_freereq(struct cryptop *crp) struct cryptop * crypto_getreq(int num) { - struct cryptodesc *crd; - struct cryptop *crp; - int s = splimp(); - - if (crypto_pool_initialized == 0) - { - pool_init(&cryptop_pool, sizeof(struct cryptop), 0, 0, PR_FREEHEADER, - "cryptop", 0, NULL, NULL, M_CRYPTO_OPS); - - pool_init(&cryptodesc_pool, sizeof(struct cryptodesc), 0, 0, - PR_FREEHEADER, "cryptodesc", 0, NULL, NULL, M_CRYPTO_OPS); - crypto_pool_initialized = 1; - } - - crp = pool_get(&cryptop_pool, 0); - if (crp == NULL) - { - splx(s); - return NULL; - } - - bzero(crp, sizeof(struct cryptop)); - - while (num--) - { - crd = pool_get(&cryptodesc_pool, 0); - if (crd == NULL) - { - splx(s); - crypto_freereq(crp); - return NULL; + struct cryptodesc *crd; + struct cryptop *crp; + int s = splimp(); + + if (crypto_pool_initialized == 0) { + pool_init(&cryptop_pool, sizeof(struct cryptop), 0, 0, + PR_FREEHEADER, "cryptop", 0, NULL, NULL, M_CRYPTO_OPS); + pool_init(&cryptodesc_pool, sizeof(struct cryptodesc), 0, 0, + PR_FREEHEADER, "cryptodesc", 0, NULL, NULL, M_CRYPTO_OPS); + crypto_pool_initialized = 1; } - bzero(crd, sizeof(struct cryptodesc)); - crd->crd_next = crp->crp_desc; - crp->crp_desc = crd; - } + crp = pool_get(&cryptop_pool, 0); + if (crp == NULL) { + splx(s); + return NULL; + } + bzero(crp, sizeof(struct cryptop)); + + while (num--) { + crd = pool_get(&cryptodesc_pool, 0); + if (crd == NULL) { + splx(s); + crypto_freereq(crp); + return NULL; + } + + bzero(crd, sizeof(struct cryptodesc)); + crd->crd_next = crp->crp_desc; + crp->crp_desc = crd; + } - splx(s); - return crp; + splx(s); + return crp; } /* @@ -467,25 +440,22 @@ crypto_getreq(int num) void crypto_thread(void) { - struct cryptop *crp; - int s; - - s = splimp(); - - for (;;) - { - crp = crp_req_queue; - if (crp == NULL) /* No work to do */ - { - (void) tsleep(&crp_req_queue, PLOCK, "crypto_wait", 0); - continue; - } + struct cryptop *crp; + int s; - /* Remove from the queue */ - crp_req_queue = crp->crp_next; + s = splimp(); - crypto_invoke(crp); - } + for (;;) { + crp = crp_req_queue; + if (crp == NULL) { + (void) tsleep(&crp_req_queue, PLOCK, "crypto_wait", 0); + continue; + } + + /* Remove from the queue */ + crp_req_queue = crp->crp_next; + crypto_invoke(crp); + } } /* @@ -494,5 +464,5 @@ crypto_thread(void) void crypto_done(struct cryptop *crp) { - crp->crp_callback(crp); + crp->crp_callback(crp); } |