svn commit: r367409 - head/sys/opencrypto

John Baldwin jhb at FreeBSD.org
Fri Nov 6 00:10:59 UTC 2020


Author: jhb
Date: Fri Nov  6 00:10:58 2020
New Revision: 367409
URL: https://svnweb.freebsd.org/changeset/base/367409

Log:
  Split logic to create new sessions into a separate function.
  
  This simplifies cryptof_ioctl as it now a wrapper around functions that
  contain the bulk of the per-ioctl logic.
  
  Reviewed by:	markj
  Sponsored by:	Chelsio Communications
  Differential Revision:	https://reviews.freebsd.org/D27068

Modified:
  head/sys/opencrypto/cryptodev.c

Modified: head/sys/opencrypto/cryptodev.c
==============================================================================
--- head/sys/opencrypto/cryptodev.c	Fri Nov  6 00:07:46 2020	(r367408)
+++ head/sys/opencrypto/cryptodev.c	Fri Nov  6 00:10:58 2020	(r367409)
@@ -415,26 +415,318 @@ checkforsoftware(int *cridp)
 	return 0;
 }
 
+static int
+cryptodev_create_session(struct fcrypt *fcr, struct session2_op *sop)
+{
+	struct crypto_session_params csp;
+	struct csession *cse;
+	struct enc_xform *txform;
+	struct auth_hash *thash;
+	void *key = NULL;
+	void *mackey = NULL;
+	crypto_session_t cses;
+	int crid, error;
+
+	switch (sop->cipher) {
+	case 0:
+		txform = NULL;
+		break;
+	case CRYPTO_AES_CBC:
+		txform = &enc_xform_rijndael128;
+		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;
+	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;
+#ifdef COMPAT_FREEBSD12
+	case CRYPTO_AES_128_NIST_GMAC:
+	case CRYPTO_AES_192_NIST_GMAC:
+	case CRYPTO_AES_256_NIST_GMAC:
+		/* Should always be paired with GCM. */
+		if (sop->cipher != CRYPTO_AES_NIST_GCM_16) {
+			CRYPTDEB("GMAC without GCM");
+			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");
+			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
+			return (EINVAL);
+		}
+		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);
+			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
+			return (EINVAL);
+		}
+		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);
+	}
+
+	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 (txform != NULL && thash != NULL)
+		csp.csp_mode = CSP_MODE_ETA;
+	else if (txform != NULL)
+		csp.csp_mode = CSP_MODE_CIPHER;
+	else
+		csp.csp_mode = CSP_MODE_DIGEST;
+
+	switch (csp.csp_mode) {
+	case CSP_MODE_AEAD:
+	case CSP_MODE_ETA:
+		if (use_separate_aad)
+			csp.csp_flags |= CSP_F_SEPARATE_AAD;
+		break;
+	}
+
+	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");
+			error = EINVAL;
+			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
+			goto bail;
+		}
+
+		key = malloc(csp.csp_cipher_klen, M_XDATA, M_WAITOK);
+		error = copyin(sop->key, key, csp.csp_cipher_klen);
+		if (error) {
+			CRYPTDEB("invalid key");
+			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
+			goto bail;
+		}
+		csp.csp_cipher_key = key;
+		csp.csp_ivlen = txform->ivsize;
+	}
+
+	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;
+			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
+			goto bail;
+		}
+
+		if (csp.csp_auth_klen != 0) {
+			mackey = malloc(csp.csp_auth_klen, M_XDATA, M_WAITOK);
+			error = copyin(sop->mackey, mackey, csp.csp_auth_klen);
+			if (error) {
+				CRYPTDEB("invalid mac key");
+				SDT_PROBE1(opencrypto, dev, ioctl, error,
+				    __LINE__);
+				goto bail;
+			}
+			csp.csp_auth_key = mackey;
+		}
+
+		if (csp.csp_auth_alg == CRYPTO_AES_NIST_GMAC)
+			csp.csp_ivlen = AES_GCM_IV_LEN;
+		if (csp.csp_auth_alg == CRYPTO_AES_CCM_CBC_MAC)
+			csp.csp_ivlen = AES_CCM_IV_LEN;
+	}
+
+	crid = sop->crid;
+	error = checkforsoftware(&crid);
+	if (error) {
+		CRYPTDEB("checkforsoftware");
+		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
+		goto bail;
+	}
+	error = crypto_newsession(&cses, &csp, crid);
+	if (error) {
+		CRYPTDEB("crypto_newsession");
+		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
+		goto bail;
+	}
+
+	cse = csecreate(fcr, cses, &csp, txform, key, thash, mackey);
+
+	if (cse == NULL) {
+		crypto_freesession(cses);
+		error = EINVAL;
+		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
+		CRYPTDEB("csecreate");
+		goto bail;
+	}
+	sop->ses = cse->ses;
+
+	/* return hardware/driver id */
+	sop->crid = crypto_ses2hid(cse->cses);
+bail:
+	if (error) {
+		free(key, M_XDATA);
+		free(mackey, M_XDATA);
+	}
+	return (error);
+}
+
 /* ARGSUSED */
 static int
 cryptof_ioctl(struct file *fp, u_long cmd, void *data,
     struct ucred *active_cred, struct thread *td)
 {
 	static struct timeval keywarn, featwarn;
-	struct crypto_session_params csp;
 	struct fcrypt *fcr = fp->f_data;
 	struct csession *cse;
 	struct session2_op *sop;
 	struct crypt_op *cop;
 	struct crypt_aead *caead;
-	struct enc_xform *txform = NULL;
-	struct auth_hash *thash = NULL;
-	void *key = NULL;
-	void *mackey = NULL;
 	struct crypt_kop *kop;
-	crypto_session_t cses;
 	uint32_t ses;
-	int error = 0, crid;
+	int error = 0;
 	union {
 		struct session2_op sopc;
 #ifdef COMPAT_FREEBSD32
@@ -502,302 +794,7 @@ cryptof_ioctl(struct file *fp, u_long cmd, void *data,
 		} else
 			sop = (struct session2_op *)data;
 
-		switch (sop->cipher) {
-		case 0:
-			break;
-		case CRYPTO_AES_CBC:
-			txform = &enc_xform_rijndael128;
-			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;
-
-		default:
-			CRYPTDEB("invalid cipher");
-			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
-			return (EINVAL);
-		}
-
-		switch (sop->mac) {
-		case 0:
-			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:
-			/* Should always be paired with GCM. */
-			if (sop->cipher != CRYPTO_AES_NIST_GCM_16) {
-				CRYPTDEB("GMAC without GCM");
-				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");
-				SDT_PROBE1(opencrypto, dev, ioctl, error,
-				    __LINE__);
-				return (EINVAL);
-			}
-			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);
-				SDT_PROBE1(opencrypto, dev, ioctl,
-				    error, __LINE__);
-				return (EINVAL);
-			}
-			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);
-		}
-
-		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 (txform && thash)
-			csp.csp_mode = CSP_MODE_ETA;
-		else if (txform)
-			csp.csp_mode = CSP_MODE_CIPHER;
-		else
-			csp.csp_mode = CSP_MODE_DIGEST;
-
-		switch (csp.csp_mode) {
-		case CSP_MODE_AEAD:
-		case CSP_MODE_ETA:
-			if (use_separate_aad)
-				csp.csp_flags |= CSP_F_SEPARATE_AAD;
-			break;
-		}
-
-		if (txform) {
-			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");
-				error = EINVAL;
-				SDT_PROBE1(opencrypto, dev, ioctl, error,
-				    __LINE__);
-				goto bail;
-			}
-
-			key = malloc(csp.csp_cipher_klen, M_XDATA, M_WAITOK);
-			error = copyin(sop->key, key, csp.csp_cipher_klen);
-			if (error) {
-				CRYPTDEB("invalid key");
-				SDT_PROBE1(opencrypto, dev, ioctl, error,
-				    __LINE__);
-				goto bail;
-			}
-			csp.csp_cipher_key = key;
-			csp.csp_ivlen = txform->ivsize;
-		}
-
-		if (thash) {
-			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;
-				SDT_PROBE1(opencrypto, dev, ioctl, error,
-				    __LINE__);
-				goto bail;
-			}
-
-			if (csp.csp_auth_klen) {
-				mackey = malloc(csp.csp_auth_klen, M_XDATA,
-				    M_WAITOK);
-				error = copyin(sop->mackey, mackey,
-				    csp.csp_auth_klen);
-				if (error) {
-					CRYPTDEB("invalid mac key");
-					SDT_PROBE1(opencrypto, dev, ioctl,
-					    error, __LINE__);
-					goto bail;
-				}
-				csp.csp_auth_key = mackey;
-			}
-
-			if (csp.csp_auth_alg == CRYPTO_AES_NIST_GMAC)
-				csp.csp_ivlen = AES_GCM_IV_LEN;
-			if (csp.csp_auth_alg == CRYPTO_AES_CCM_CBC_MAC)
-				csp.csp_ivlen = AES_CCM_IV_LEN;
-		}
-
-		crid = sop->crid;
-		error = checkforsoftware(&crid);
-		if (error) {
-			CRYPTDEB("checkforsoftware");
-			SDT_PROBE1(opencrypto, dev, ioctl, error,
-			    __LINE__);
-			goto bail;
-		}
-		error = crypto_newsession(&cses, &csp, crid);
-		if (error) {
-			CRYPTDEB("crypto_newsession");
-			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
-			goto bail;
-		}
-
-		cse = csecreate(fcr, cses, &csp, txform, key, thash, mackey);
-
-		if (cse == NULL) {
-			crypto_freesession(cses);
-			error = EINVAL;
-			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
-			CRYPTDEB("csecreate");
-			goto bail;
-		}
-		sop->ses = cse->ses;
-
-		/* return hardware/driver id */
-		sop->crid = crypto_ses2hid(cse->cses);
-bail:
-		if (error) {
-			free(key, M_XDATA);
-			free(mackey, M_XDATA);
-		}
-
+		error = cryptodev_create_session(fcr, sop);
 		if (cmd == CIOCGSESSION && error == 0)
 			session2_op_to_op(sop, data);
 		break;


More information about the svn-src-all mailing list