diff --git a/sys/kgssapi/krb5/kcrypto_aes.c b/sys/kgssapi/krb5/kcrypto_aes.c --- a/sys/kgssapi/krb5/kcrypto_aes.c +++ b/sys/kgssapi/krb5/kcrypto_aes.c @@ -119,18 +119,28 @@ static int aes_crypto_cb(struct cryptop *crp) { + struct aes_state *as = (struct aes_state *)crp->crp_opaque; int error; - struct aes_state *as = (struct aes_state *) crp->crp_opaque; + + error = crp->crp_etype; + if (error != 0) { + if (error == EAGAIN) + return (crypto_dispatch(crp)); + + /* + * Currently there is no way to report errors to upper layers, + * so we have no choice but to panic. + */ + panic("%s: crypto operation failed with error %d", __func__, + error); + } if (CRYPTO_SESS_SYNC(crp->crp_session)) return (0); - error = crp->crp_etype; - if (error == EAGAIN) - error = crypto_dispatch(crp); mtx_lock(&as->as_lock); - if (error || (crp->crp_flags & CRYPTO_F_DONE)) - wakeup(crp); + crp->crp_opaque = NULL; + wakeup(crp); mtx_unlock(&as->as_lock); return (0); @@ -164,11 +174,10 @@ crp->crp_callback = aes_crypto_cb; error = crypto_dispatch(crp); - - if (!CRYPTO_SESS_SYNC(as->as_session_aes)) { + if (error == 0 && !CRYPTO_SESS_SYNC(as->as_session_aes)) { mtx_lock(&as->as_lock); - if (!error && !(crp->crp_flags & CRYPTO_F_DONE)) - error = msleep(crp, &as->as_lock, 0, "gssaes", 0); + while (crp->crp_opaque != NULL) + (void)msleep(crp, &as->as_lock, 0, "gssaes", 0); mtx_unlock(&as->as_lock); } @@ -334,11 +343,10 @@ crp->crp_callback = aes_crypto_cb; error = crypto_dispatch(crp); - - if (!CRYPTO_SESS_SYNC(as->as_session_sha1)) { + if (error == 0 && !CRYPTO_SESS_SYNC(as->as_session_sha1)) { mtx_lock(&as->as_lock); - if (!error && !(crp->crp_flags & CRYPTO_F_DONE)) - error = msleep(crp, &as->as_lock, 0, "gssaes", 0); + while (crp->crp_opaque != NULL) + (void)msleep(crp, &as->as_lock, 0, "gssaes", 0); mtx_unlock(&as->as_lock); }