diff options
author | Angelos D. Keromytis <angelos@cvs.openbsd.org> | 2002-07-16 06:12:47 +0000 |
---|---|---|
committer | Angelos D. Keromytis <angelos@cvs.openbsd.org> | 2002-07-16 06:12:47 +0000 |
commit | 1aa941746340b81f386141b6c03b56fae02e6e08 (patch) | |
tree | 6fb24bbe2a108cbcaf780d6725124742d9cbd65c /sys/crypto | |
parent | a4268f4ee1e9f6a20e54c83625ccb6bd88670bb7 (diff) |
Fix a typo, cleanup on session migration code in crypto_invoke(), and
add a convention that if the driver returns ERESTART as an error
message of its process method, the crypto framework will unregister
the driver and migrate all its sessions. After discussion with Sam
Leffler and Jason Wright.
Diffstat (limited to 'sys/crypto')
-rw-r--r-- | sys/crypto/crypto.c | 82 |
1 files changed, 44 insertions, 38 deletions
diff --git a/sys/crypto/crypto.c b/sys/crypto/crypto.c index e5c8731a3d6..9b6239bd9fb 100644 --- a/sys/crypto/crypto.c +++ b/sys/crypto/crypto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: crypto.c,v 1.38 2002/06/11 11:14:29 beck Exp $ */ +/* $OpenBSD: crypto.c,v 1.39 2002/07/16 06:12:46 angelos Exp $ */ /* * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu) * @@ -303,26 +303,33 @@ crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen, int crypto_unregister(u_int32_t driverid, int alg) { - int i, s = splimp(); + int i = CRYPTO_ALGORITHM_MAX + 1, s = splimp(); u_int32_t ses; /* Sanity checks */ - if (driverid >= crypto_drivers_num || alg <= 0 || - alg > CRYPTO_ALGORITHM_MAX || crypto_drivers == NULL || + if (driverid >= crypto_drivers_num || crypto_drivers == NULL || + ((alg <= 0 || alg > CRYPTO_ALGORITHM_MAX) && + alg != CRYPTO_ALGORITHM_ALL) || crypto_drivers[driverid].cc_alg[alg] == 0) { splx(s); return EINVAL; } - crypto_drivers[driverid].cc_alg[alg] = 0; - crypto_drivers[driverid].cc_max_op_len[alg] = 0; + if (alg != CRYPTO_ALGORITHM_ALL) { + crypto_drivers[driverid].cc_alg[alg] = 0; + crypto_drivers[driverid].cc_max_op_len[alg] = 0; - /* Was this the last algorithm ? */ - for (i = 1; i <= CRYPTO_ALGORITHM_MAX; i++) - if (crypto_drivers[driverid].cc_alg[i] != 0) - break; + /* 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) { + /* + * If a driver unregistered its last algorithm or all of them + * (alg == CRYPTO_ALGORITHM_ALL), cleanup its entry. + */ + if (i == CRYPTO_ALGORITHM_MAX + 1 || alg == CRYPTO_ALGORITHM_ALL) { ses = crypto_drivers[driverid].cc_sessions; bzero(&crypto_drivers[driverid], sizeof(struct cryptocap)); if (ses != 0) { @@ -377,7 +384,7 @@ crypto_kdispatch(struct cryptkop *krp) } /* - * Dispatch an assymetric crypto request to the appropriate crypto devices. + * Dispatch an asymmetric crypto request to the appropriate crypto devices. */ int crypto_kinvoke(struct cryptkop *krp) @@ -437,40 +444,39 @@ crypto_invoke(struct cryptop *crp) } 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 (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI), 0) == 0) - crp->crp_sid = nid; - - crp->crp_etype = EAGAIN; - crypto_done(crp); - return 0; - } + if (hid >= crypto_drivers_num) + goto migrate; 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_newsession(&nid, &(crp->crp_desc->CRD_INI), 0) == 0) - crp->crp_sid = nid; - - crp->crp_etype = EAGAIN; - crypto_done(crp); - return 0; - } + if (crypto_drivers[hid].cc_process == NULL) + goto migrate; error = crypto_drivers[hid].cc_process(crp); if (error) { - crp->crp_etype = error; - crypto_done(crp); + if (error == ERESTART) { + /* Unregister driver and migrate session. */ + crypto_unregister(hid, CRYPTO_ALGORITHM_ALL); + goto migrate; + } else { + crp->crp_etype = error; + crypto_done(crp); + } } + + return 0; + + migrate: + /* 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; + + crp->crp_etype = EAGAIN; + crypto_done(crp); return 0; } |