/dev/crypto: Minimize cipher-specific logic.

Rather than duplicating the switches in crypto_auth_hash() and
crypto_cipher(), copy the algorithm constants from the new session
ioctl into a csp directly which permits using the functions in
crypto.c.

Reviewed by:	markj
Sponsored by:	Chelsio Communications
Differential Revision:	https://reviews.freebsd.org/D33613
This commit is contained in:
John Baldwin 2021-12-29 17:50:03 -08:00
parent c3a688ef4d
commit c3907ef482

View file

@ -339,71 +339,11 @@ cse_create(struct fcrypt *fcr, struct session2_op *sop)
void *key = NULL;
void *mackey = NULL;
crypto_session_t cses;
int crid, error;
int crid, error, mac;
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;
default:
CRYPTDEB("invalid cipher");
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL);
}
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;
mac = sop->mac;
#ifdef COMPAT_FREEBSD12
switch (sop->mac) {
case CRYPTO_AES_128_NIST_GMAC:
case CRYPTO_AES_192_NIST_GMAC:
case CRYPTO_AES_256_NIST_GMAC:
@ -413,138 +353,58 @@ cse_create(struct fcrypt *fcr, struct session2_op *sop)
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);
}
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);
}
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 (mac != 0) {
csp.csp_auth_alg = mac;
csp.csp_auth_klen = sop->mackeylen;
}
if (sop->cipher != 0) {
csp.csp_cipher_alg = sop->cipher;
csp.csp_cipher_klen = sop->keylen;
}
thash = crypto_auth_hash(&csp);
txform = crypto_cipher(&csp);
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:
if (txform != NULL && txform->macsize != 0) {
if (mac != 0) {
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->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 (txform != NULL && thash != NULL) {
csp.csp_mode = CSP_MODE_ETA;
else if (txform != NULL)
} else if (txform != NULL) {
csp.csp_mode = CSP_MODE_CIPHER;
else
} else if (thash != NULL) {
csp.csp_mode = CSP_MODE_DIGEST;
} else {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL);
}
switch (csp.csp_mode) {
case CSP_MODE_AEAD:
@ -555,8 +415,6 @@ cse_create(struct fcrypt *fcr, struct session2_op *sop)
}
if (txform != NULL) {
csp.csp_cipher_alg = txform->type;
csp.csp_cipher_klen = sop->keylen;
if (sop->keylen > txform->maxkey ||
sop->keylen < txform->minkey) {
CRYPTDEB("invalid cipher parameters");
@ -577,8 +435,6 @@ cse_create(struct fcrypt *fcr, struct session2_op *sop)
}
if (thash != NULL) {
csp.csp_auth_alg = thash->type;
csp.csp_auth_klen = sop->mackeylen;
if (sop->mackeylen > thash->keysize || sop->mackeylen < 0) {
CRYPTDEB("invalid mac key length");
error = EINVAL;