From 4cf841fb608c4994fc68b5c9d9d3bfd999bfcfa5 Mon Sep 17 00:00:00 2001 From: jhb Date: Thu, 5 Nov 2020 23:31:58 +0000 Subject: [PATCH] Check cipher key lengths during probesession. OCF drivers in general should perform as many session parameter checks as possible during probesession rather than when creating a new session. I got this wrong for aesni(4) in r359374. In addition, aesni(4) was performing the check for digest-only requests and failing to create digest-only sessions as a result. Reported by: jkim Tested by: jkim Sponsored by: Chelsio Communications --- sys/crypto/aesni/aesni.c | 80 ++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/sys/crypto/aesni/aesni.c b/sys/crypto/aesni/aesni.c index ac2a242c21b..709d1558ee8 100644 --- a/sys/crypto/aesni/aesni.c +++ b/sys/crypto/aesni/aesni.c @@ -237,16 +237,35 @@ aesni_cipher_supported(struct aesni_softc *sc, switch (csp->csp_cipher_alg) { case CRYPTO_AES_CBC: case CRYPTO_AES_ICM: + switch (csp->csp_cipher_klen * 8) { + case 128: + case 192: + case 256: + break; + default: + CRYPTDEB("invalid CBC/ICM key length"); + return (false); + } if (csp->csp_ivlen != AES_BLOCK_LEN) return (false); - return (sc->has_aes); + break; case CRYPTO_AES_XTS: + switch (csp->csp_cipher_klen * 8) { + case 256: + case 512: + break; + default: + CRYPTDEB("invalid XTS key length"); + return (false); + } if (csp->csp_ivlen != AES_XTS_IV_LEN) return (false); - return (sc->has_aes); + break; default: return (false); } + + return (true); } #define SUPPORTED_SES (CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD | CSP_F_ESN) @@ -271,6 +290,15 @@ aesni_probesession(device_t dev, const struct crypto_session_params *csp) case CSP_MODE_AEAD: switch (csp->csp_cipher_alg) { case CRYPTO_AES_NIST_GCM_16: + switch (csp->csp_cipher_klen * 8) { + case 128: + case 192: + case 256: + break; + default: + CRYPTDEB("invalid GCM key length"); + return (EINVAL); + } if (csp->csp_auth_mlen != 0 && csp->csp_auth_mlen != GMAC_DIGEST_LEN) return (EINVAL); @@ -279,6 +307,15 @@ aesni_probesession(device_t dev, const struct crypto_session_params *csp) return (EINVAL); break; case CRYPTO_AES_CCM_16: + switch (csp->csp_cipher_klen * 8) { + case 128: + case 192: + case 256: + break; + default: + CRYPTDEB("invalid CCM key length"); + return (EINVAL); + } if (csp->csp_auth_mlen != 0 && csp->csp_auth_mlen != AES_CBC_MAC_HASH_LEN) return (EINVAL); @@ -518,41 +555,6 @@ aesni_authprepare(struct aesni_session *ses, int klen) return (0); } -static int -aesni_cipherprepare(const struct crypto_session_params *csp) -{ - - switch (csp->csp_cipher_alg) { - case CRYPTO_AES_ICM: - case CRYPTO_AES_NIST_GCM_16: - case CRYPTO_AES_CCM_16: - case CRYPTO_AES_CBC: - switch (csp->csp_cipher_klen * 8) { - case 128: - case 192: - case 256: - break; - default: - CRYPTDEB("invalid CBC/ICM/GCM key length"); - return (EINVAL); - } - break; - case CRYPTO_AES_XTS: - switch (csp->csp_cipher_klen * 8) { - case 256: - case 512: - break; - default: - CRYPTDEB("invalid XTS key length"); - return (EINVAL); - } - break; - default: - return (EINVAL); - } - return (0); -} - static int aesni_cipher_setup(struct aesni_session *ses, const struct crypto_session_params *csp) @@ -601,10 +603,6 @@ aesni_cipher_setup(struct aesni_session *ses, return (error); } - error = aesni_cipherprepare(csp); - if (error != 0) - return (error); - kt = is_fpu_kern_thread(0) || (csp->csp_cipher_alg == 0); if (!kt) { ACQUIRE_CTX(ctxidx, ctx); -- 2.45.0