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;
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to