Index: sys/opencrypto/cryptodev.c =================================================================== --- sys/opencrypto/cryptodev.c +++ sys/opencrypto/cryptodev.c @@ -341,72 +341,8 @@ crypto_session_t cses; int crid, error; - switch (sop->cipher) { - case 0: - txform = NULL; - break; - case CRYPTO_AES_CBC: - txform = &enc_xform_aes_cbc; - break; - case CRYPTO_AES_XTS: - txform = &enc_xform_aes_xts; - break; - case CRYPTO_NULL_CBC: - txform = &enc_xform_null; - break; - case CRYPTO_CAMELLIA_CBC: - txform = &enc_xform_camellia; - break; - case CRYPTO_AES_ICM: - txform = &enc_xform_aes_icm; - break; - case CRYPTO_AES_NIST_GCM_16: - txform = &enc_xform_aes_nist_gcm; - break; - case CRYPTO_CHACHA20: - txform = &enc_xform_chacha20; - break; - case CRYPTO_AES_CCM_16: - txform = &enc_xform_ccm; - break; - case CRYPTO_CHACHA20_POLY1305: - txform = &enc_xform_chacha20_poly1305; - break; - case CRYPTO_XCHACHA20_POLY1305: - txform = &enc_xform_xchacha20_poly1305; - break; - default: - CRYPTDEB("invalid cipher"); - SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); - return (EINVAL); - } - +#ifdef COMPAT_FREEBSD12 switch (sop->mac) { - case 0: - thash = NULL; - break; - case CRYPTO_POLY1305: - thash = &auth_hash_poly1305; - break; - case CRYPTO_SHA1_HMAC: - thash = &auth_hash_hmac_sha1; - break; - case CRYPTO_SHA2_224_HMAC: - thash = &auth_hash_hmac_sha2_224; - break; - case CRYPTO_SHA2_256_HMAC: - thash = &auth_hash_hmac_sha2_256; - break; - case CRYPTO_SHA2_384_HMAC: - thash = &auth_hash_hmac_sha2_384; - break; - case CRYPTO_SHA2_512_HMAC: - thash = &auth_hash_hmac_sha2_512; - break; - case CRYPTO_RIPEMD160_HMAC: - thash = &auth_hash_hmac_ripemd_160; - break; -#ifdef COMPAT_FREEBSD12 case CRYPTO_AES_128_NIST_GMAC: case CRYPTO_AES_192_NIST_GMAC: case CRYPTO_AES_256_NIST_GMAC: @@ -416,139 +352,51 @@ SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); return (EINVAL); } - break; -#endif - case CRYPTO_AES_NIST_GMAC: - switch (sop->mackeylen * 8) { - case 128: - thash = &auth_hash_nist_gmac_aes_128; - break; - case 192: - thash = &auth_hash_nist_gmac_aes_192; - break; - case 256: - thash = &auth_hash_nist_gmac_aes_256; - break; - default: - CRYPTDEB("invalid GMAC key length"); + if (sop->keylen != sop->mackeylen) { SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); return (EINVAL); } + sop->mac = 0; break; case CRYPTO_AES_CCM_CBC_MAC: - switch (sop->mackeylen) { - case 16: - thash = &auth_hash_ccm_cbc_mac_128; - break; - case 24: - thash = &auth_hash_ccm_cbc_mac_192; - break; - case 32: - thash = &auth_hash_ccm_cbc_mac_256; - break; - default: - CRYPTDEB("Invalid CBC MAC key size %d", sop->keylen); + /* Should always be paired with CCM. */ + if (sop->cipher != CRYPTO_AES_CCM_16) { + CRYPTDEB("CBC-MAC without CCM"); SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); return (EINVAL); } + if (sop->keylen != sop->mackeylen) { + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); + return (EINVAL); + } + sop->mac = 0; break; - case CRYPTO_RIPEMD160: - thash = &auth_hash_ripemd_160; - break; - case CRYPTO_SHA1: - thash = &auth_hash_sha1; - break; - case CRYPTO_SHA2_224: - thash = &auth_hash_sha2_224; - break; - case CRYPTO_SHA2_256: - thash = &auth_hash_sha2_256; - break; - case CRYPTO_SHA2_384: - thash = &auth_hash_sha2_384; - break; - case CRYPTO_SHA2_512: - thash = &auth_hash_sha2_512; - break; - - case CRYPTO_NULL_HMAC: - thash = &auth_hash_null; - break; - - case CRYPTO_BLAKE2B: - thash = &auth_hash_blake2b; - break; - case CRYPTO_BLAKE2S: - thash = &auth_hash_blake2s; - break; - - default: - CRYPTDEB("invalid mac"); - SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); - return (EINVAL); - } - - if (txform == NULL && thash == NULL) { - SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); - return (EINVAL); } +#endif memset(&csp, 0, sizeof(csp)); if (use_outputbuffers) csp.csp_flags |= CSP_F_SEPARATE_OUTPUT; - if (sop->cipher == CRYPTO_AES_NIST_GCM_16) { - switch (sop->mac) { -#ifdef COMPAT_FREEBSD12 - case CRYPTO_AES_128_NIST_GMAC: - case CRYPTO_AES_192_NIST_GMAC: - case CRYPTO_AES_256_NIST_GMAC: - if (sop->keylen != sop->mackeylen) { - SDT_PROBE1(opencrypto, dev, ioctl, error, - __LINE__); - return (EINVAL); - } - break; -#endif - case 0: - break; - default: - SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); - return (EINVAL); - } - csp.csp_mode = CSP_MODE_AEAD; - } else if (sop->cipher == CRYPTO_AES_CCM_16) { - switch (sop->mac) { -#ifdef COMPAT_FREEBSD12 - case CRYPTO_AES_CCM_CBC_MAC: - if (sop->keylen != sop->mackeylen) { - SDT_PROBE1(opencrypto, dev, ioctl, error, - __LINE__); - return (EINVAL); - } - thash = NULL; - break; -#endif - case 0: - break; - default: - SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); - return (EINVAL); - } - csp.csp_mode = CSP_MODE_AEAD; - } else if (sop->cipher == CRYPTO_CHACHA20_POLY1305 || + if (sop->cipher == CRYPTO_AES_NIST_GCM_16 || + sop->cipher == CRYPTO_AES_CCM_16 || + sop->cipher == CRYPTO_CHACHA20_POLY1305 || sop->cipher == CRYPTO_XCHACHA20_POLY1305) { if (sop->mac != 0) { SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); return (EINVAL); } csp.csp_mode = CSP_MODE_AEAD; - } else if (txform != NULL && thash != NULL) + } else if (sop->cipher != 0 && sop->mac != 0) { csp.csp_mode = CSP_MODE_ETA; - else if (txform != NULL) + } else if (sop->cipher != 0) { csp.csp_mode = CSP_MODE_CIPHER; - else + } else if (sop->mac != 0) { csp.csp_mode = CSP_MODE_DIGEST; + } else { + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); + return (EINVAL); + } switch (csp.csp_mode) { case CSP_MODE_AEAD: @@ -558,9 +406,15 @@ break; } - if (txform != NULL) { - csp.csp_cipher_alg = txform->type; + if (sop->cipher != 0) { + csp.csp_cipher_alg = sop->cipher; csp.csp_cipher_klen = sop->keylen; + txform = crypto_cipher(&csp); + if (txform == NULL) { + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); + return (EINVAL); + } + if (sop->keylen > txform->maxkey || sop->keylen < txform->minkey) { CRYPTDEB("invalid cipher parameters"); @@ -578,11 +432,18 @@ } csp.csp_cipher_key = key; csp.csp_ivlen = txform->ivsize; - } + } else + txform = NULL; - if (thash != NULL) { - csp.csp_auth_alg = thash->type; + if (sop->mac != 0) { + csp.csp_auth_alg = sop->mac; csp.csp_auth_klen = sop->mackeylen; + thash = crypto_auth_hash(&csp); + if (thash == NULL) { + SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); + return (EINVAL); + } + if (sop->mackeylen > thash->keysize || sop->mackeylen < 0) { CRYPTDEB("invalid mac key length"); error = EINVAL; @@ -606,7 +467,8 @@ csp.csp_ivlen = AES_GCM_IV_LEN; if (csp.csp_auth_alg == CRYPTO_AES_CCM_CBC_MAC) csp.csp_ivlen = AES_CCM_IV_LEN; - } + } else + thash = NULL; if (sop->ivlen != 0) { if (csp.csp_ivlen == 0) {