The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/opencrypto/cryptodev.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $OpenBSD: cryptodev.c,v 1.52 2002/06/19 07:22:46 deraadt Exp $  */
    2 
    3 /*-
    4  * Copyright (c) 2001 Theo de Raadt
    5  * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
    6  * Copyright (c) 2014 The FreeBSD Foundation
    7  * All rights reserved.
    8  *
    9  * Portions of this software were developed by John-Mark Gurney
   10  * under sponsorship of the FreeBSD Foundation and
   11  * Rubicon Communications, LLC (Netgate).
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  *
   17  * 1. Redistributions of source code must retain the above copyright
   18  *   notice, this list of conditions and the following disclaimer.
   19  * 2. Redistributions in binary form must reproduce the above copyright
   20  *   notice, this list of conditions and the following disclaimer in the
   21  *   documentation and/or other materials provided with the distribution.
   22  * 3. The name of the author may not be used to endorse or promote products
   23  *   derived from this software without specific prior written permission.
   24  *
   25  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   26  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   27  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   28  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   30  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   31  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   32  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   33  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   34  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   35  *
   36  * Effort sponsored in part by the Defense Advanced Research Projects
   37  * Agency (DARPA) and Air Force Research Laboratory, Air Force
   38  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
   39  */
   40 
   41 #include <sys/cdefs.h>
   42 __FBSDID("$FreeBSD$");
   43 
   44 #include <sys/param.h>
   45 #include <sys/systm.h>
   46 #include <sys/malloc.h>
   47 #include <sys/mbuf.h>
   48 #include <sys/lock.h>
   49 #include <sys/mutex.h>
   50 #include <sys/proc.h>
   51 #include <sys/sysctl.h>
   52 #include <sys/errno.h>
   53 #include <sys/random.h>
   54 #include <sys/conf.h>
   55 #include <sys/kernel.h>
   56 #include <sys/module.h>
   57 #include <sys/fcntl.h>
   58 #include <sys/bus.h>
   59 #include <sys/sdt.h>
   60 #include <sys/syscallsubr.h>
   61 
   62 #include <opencrypto/cryptodev.h>
   63 #include <opencrypto/xform.h>
   64 
   65 SDT_PROVIDER_DECLARE(opencrypto);
   66 
   67 SDT_PROBE_DEFINE1(opencrypto, dev, ioctl, error, "int"/*line number*/);
   68 
   69 #ifdef COMPAT_FREEBSD12
   70 /*
   71  * Previously, most ioctls were performed against a cloned descriptor
   72  * of /dev/crypto obtained via CRIOGET.  Now all ioctls are performed
   73  * against /dev/crypto directly.
   74  */
   75 #define CRIOGET         _IOWR('c', 100, uint32_t)
   76 #endif
   77 
   78 /* the following are done against the cloned descriptor */
   79 
   80 #ifdef COMPAT_FREEBSD32
   81 #include <sys/mount.h>
   82 #include <compat/freebsd32/freebsd32.h>
   83 
   84 struct session_op32 {
   85         uint32_t        cipher;
   86         uint32_t        mac;
   87         uint32_t        keylen;
   88         uint32_t        key;
   89         int             mackeylen;
   90         uint32_t        mackey;
   91         uint32_t        ses;
   92 };
   93 
   94 struct session2_op32 {
   95         uint32_t        cipher;
   96         uint32_t        mac;
   97         uint32_t        keylen;
   98         uint32_t        key;
   99         int             mackeylen;
  100         uint32_t        mackey;
  101         uint32_t        ses;
  102         int             crid;
  103         int             pad[4];
  104 };
  105 
  106 struct crypt_op32 {
  107         uint32_t        ses;
  108         uint16_t        op;
  109         uint16_t        flags;
  110         u_int           len;
  111         uint32_t        src, dst;
  112         uint32_t        mac;
  113         uint32_t        iv;
  114 };
  115 
  116 struct crypt_aead32 {
  117         uint32_t        ses;
  118         uint16_t        op;
  119         uint16_t        flags;
  120         u_int           len;
  121         u_int           aadlen;
  122         u_int           ivlen;
  123         uint32_t        src;
  124         uint32_t        dst;
  125         uint32_t        aad;
  126         uint32_t        tag;
  127         uint32_t        iv;
  128 };
  129 
  130 struct crparam32 {
  131         uint32_t        crp_p;
  132         u_int           crp_nbits;
  133 };
  134 
  135 struct crypt_kop32 {
  136         u_int           crk_op;
  137         u_int           crk_status;
  138         u_short         crk_iparams;
  139         u_short         crk_oparams;
  140         u_int           crk_crid;
  141         struct crparam32        crk_param[CRK_MAXPARAM];
  142 };
  143 
  144 #define CIOCGSESSION32  _IOWR('c', 101, struct session_op32)
  145 #define CIOCCRYPT32     _IOWR('c', 103, struct crypt_op32)
  146 #define CIOCKEY32       _IOWR('c', 104, struct crypt_kop32)
  147 #define CIOCGSESSION232 _IOWR('c', 106, struct session2_op32)
  148 #define CIOCKEY232      _IOWR('c', 107, struct crypt_kop32)
  149 #define CIOCCRYPTAEAD32 _IOWR('c', 109, struct crypt_aead32)
  150 
  151 static void
  152 session_op_from_32(const struct session_op32 *from, struct session2_op *to)
  153 {
  154 
  155         memset(to, 0, sizeof(*to));
  156         CP(*from, *to, cipher);
  157         CP(*from, *to, mac);
  158         CP(*from, *to, keylen);
  159         PTRIN_CP(*from, *to, key);
  160         CP(*from, *to, mackeylen);
  161         PTRIN_CP(*from, *to, mackey);
  162         CP(*from, *to, ses);
  163         to->crid = CRYPTOCAP_F_HARDWARE;
  164 }
  165 
  166 static void
  167 session2_op_from_32(const struct session2_op32 *from, struct session2_op *to)
  168 {
  169 
  170         session_op_from_32((const struct session_op32 *)from, to);
  171         CP(*from, *to, crid);
  172 }
  173 
  174 static void
  175 session_op_to_32(const struct session2_op *from, struct session_op32 *to)
  176 {
  177 
  178         CP(*from, *to, cipher);
  179         CP(*from, *to, mac);
  180         CP(*from, *to, keylen);
  181         PTROUT_CP(*from, *to, key);
  182         CP(*from, *to, mackeylen);
  183         PTROUT_CP(*from, *to, mackey);
  184         CP(*from, *to, ses);
  185 }
  186 
  187 static void
  188 session2_op_to_32(const struct session2_op *from, struct session2_op32 *to)
  189 {
  190 
  191         session_op_to_32(from, (struct session_op32 *)to);
  192         CP(*from, *to, crid);
  193 }
  194 
  195 static void
  196 crypt_op_from_32(const struct crypt_op32 *from, struct crypt_op *to)
  197 {
  198 
  199         CP(*from, *to, ses);
  200         CP(*from, *to, op);
  201         CP(*from, *to, flags);
  202         CP(*from, *to, len);
  203         PTRIN_CP(*from, *to, src);
  204         PTRIN_CP(*from, *to, dst);
  205         PTRIN_CP(*from, *to, mac);
  206         PTRIN_CP(*from, *to, iv);
  207 }
  208 
  209 static void
  210 crypt_op_to_32(const struct crypt_op *from, struct crypt_op32 *to)
  211 {
  212 
  213         CP(*from, *to, ses);
  214         CP(*from, *to, op);
  215         CP(*from, *to, flags);
  216         CP(*from, *to, len);
  217         PTROUT_CP(*from, *to, src);
  218         PTROUT_CP(*from, *to, dst);
  219         PTROUT_CP(*from, *to, mac);
  220         PTROUT_CP(*from, *to, iv);
  221 }
  222 
  223 static void
  224 crypt_aead_from_32(const struct crypt_aead32 *from, struct crypt_aead *to)
  225 {
  226 
  227         CP(*from, *to, ses);
  228         CP(*from, *to, op);
  229         CP(*from, *to, flags);
  230         CP(*from, *to, len);
  231         CP(*from, *to, aadlen);
  232         CP(*from, *to, ivlen);
  233         PTRIN_CP(*from, *to, src);
  234         PTRIN_CP(*from, *to, dst);
  235         PTRIN_CP(*from, *to, aad);
  236         PTRIN_CP(*from, *to, tag);
  237         PTRIN_CP(*from, *to, iv);
  238 }
  239 
  240 static void
  241 crypt_aead_to_32(const struct crypt_aead *from, struct crypt_aead32 *to)
  242 {
  243 
  244         CP(*from, *to, ses);
  245         CP(*from, *to, op);
  246         CP(*from, *to, flags);
  247         CP(*from, *to, len);
  248         CP(*from, *to, aadlen);
  249         CP(*from, *to, ivlen);
  250         PTROUT_CP(*from, *to, src);
  251         PTROUT_CP(*from, *to, dst);
  252         PTROUT_CP(*from, *to, aad);
  253         PTROUT_CP(*from, *to, tag);
  254         PTROUT_CP(*from, *to, iv);
  255 }
  256 
  257 static void
  258 crparam_from_32(const struct crparam32 *from, struct crparam *to)
  259 {
  260 
  261         PTRIN_CP(*from, *to, crp_p);
  262         CP(*from, *to, crp_nbits);
  263 }
  264 
  265 static void
  266 crparam_to_32(const struct crparam *from, struct crparam32 *to)
  267 {
  268 
  269         PTROUT_CP(*from, *to, crp_p);
  270         CP(*from, *to, crp_nbits);
  271 }
  272 
  273 static void
  274 crypt_kop_from_32(const struct crypt_kop32 *from, struct crypt_kop *to)
  275 {
  276         int i;
  277 
  278         CP(*from, *to, crk_op);
  279         CP(*from, *to, crk_status);
  280         CP(*from, *to, crk_iparams);
  281         CP(*from, *to, crk_oparams);
  282         CP(*from, *to, crk_crid);
  283         for (i = 0; i < CRK_MAXPARAM; i++)
  284                 crparam_from_32(&from->crk_param[i], &to->crk_param[i]);
  285 }
  286 
  287 static void
  288 crypt_kop_to_32(const struct crypt_kop *from, struct crypt_kop32 *to)
  289 {
  290         int i;
  291 
  292         CP(*from, *to, crk_op);
  293         CP(*from, *to, crk_status);
  294         CP(*from, *to, crk_iparams);
  295         CP(*from, *to, crk_oparams);
  296         CP(*from, *to, crk_crid);
  297         for (i = 0; i < CRK_MAXPARAM; i++)
  298                 crparam_to_32(&from->crk_param[i], &to->crk_param[i]);
  299 }
  300 #endif
  301 
  302 static void
  303 session2_op_from_op(const struct session_op *from, struct session2_op *to)
  304 {
  305 
  306         memset(to, 0, sizeof(*to));
  307         memcpy(to, from, sizeof(*from));
  308         to->crid = CRYPTOCAP_F_HARDWARE;
  309 }
  310 
  311 static void
  312 session2_op_to_op(const struct session2_op *from, struct session_op *to)
  313 {
  314 
  315         memcpy(to, from, sizeof(*to));
  316 }
  317 
  318 struct csession {
  319         TAILQ_ENTRY(csession) next;
  320         crypto_session_t cses;
  321         volatile u_int  refs;
  322         uint32_t        ses;
  323         struct mtx      lock;           /* for op submission */
  324 
  325         struct enc_xform *txform;
  326         int             hashsize;
  327         int             ivsize;
  328         int             mode;
  329 
  330         void            *key;
  331         void            *mackey;
  332 };
  333 
  334 struct cryptop_data {
  335         struct csession *cse;
  336 
  337         char            *buf;
  338         char            *obuf;
  339         char            *aad;
  340         bool            done;
  341 };
  342 
  343 struct fcrypt {
  344         TAILQ_HEAD(csessionlist, csession) csessions;
  345         int             sesn;
  346         struct mtx      lock;
  347 };
  348 
  349 static bool use_outputbuffers;
  350 SYSCTL_BOOL(_kern_crypto, OID_AUTO, cryptodev_use_output, CTLFLAG_RW,
  351     &use_outputbuffers, 0,
  352     "Use separate output buffers for /dev/crypto requests.");
  353 
  354 static bool use_separate_aad;
  355 SYSCTL_BOOL(_kern_crypto, OID_AUTO, cryptodev_separate_aad, CTLFLAG_RW,
  356     &use_separate_aad, 0,
  357     "Use separate AAD buffer for /dev/crypto requests.");
  358 
  359 static struct timeval warninterval = { .tv_sec = 60, .tv_usec = 0 };
  360 SYSCTL_TIMEVAL_SEC(_kern, OID_AUTO, cryptodev_warn_interval, CTLFLAG_RW,
  361     &warninterval,
  362     "Delay in seconds between warnings of deprecated /dev/crypto algorithms");
  363 
  364 /*
  365  * Check a crypto identifier to see if it requested
  366  * a software device/driver.  This can be done either
  367  * by device name/class or through search constraints.
  368  */
  369 static int
  370 checkforsoftware(int *cridp)
  371 {
  372         int crid;
  373 
  374         crid = *cridp;
  375 
  376         if (!crypto_devallowsoft) {
  377                 if (crid & CRYPTOCAP_F_SOFTWARE) {
  378                         if (crid & CRYPTOCAP_F_HARDWARE) {
  379                                 *cridp = CRYPTOCAP_F_HARDWARE;
  380                                 return 0;
  381                         }
  382                         return EINVAL;
  383                 }
  384                 if ((crid & CRYPTOCAP_F_HARDWARE) == 0 &&
  385                     (crypto_getcaps(crid) & CRYPTOCAP_F_HARDWARE) == 0)
  386                         return EINVAL;
  387         }
  388         return 0;
  389 }
  390 
  391 static int
  392 cse_create(struct fcrypt *fcr, struct session2_op *sop)
  393 {
  394         struct crypto_session_params csp;
  395         struct csession *cse;
  396         struct enc_xform *txform;
  397         struct auth_hash *thash;
  398         void *key = NULL;
  399         void *mackey = NULL;
  400         crypto_session_t cses;
  401         int crid, error;
  402 
  403         switch (sop->cipher) {
  404         case 0:
  405                 txform = NULL;
  406                 break;
  407         case CRYPTO_AES_CBC:
  408                 txform = &enc_xform_rijndael128;
  409                 break;
  410         case CRYPTO_AES_XTS:
  411                 txform = &enc_xform_aes_xts;
  412                 break;
  413         case CRYPTO_NULL_CBC:
  414                 txform = &enc_xform_null;
  415                 break;
  416         case CRYPTO_CAMELLIA_CBC:
  417                 txform = &enc_xform_camellia;
  418                 break;
  419         case CRYPTO_AES_ICM:
  420                 txform = &enc_xform_aes_icm;
  421                 break;
  422         case CRYPTO_AES_NIST_GCM_16:
  423                 txform = &enc_xform_aes_nist_gcm;
  424                 break;
  425         case CRYPTO_CHACHA20:
  426                 txform = &enc_xform_chacha20;
  427                 break;
  428         case CRYPTO_AES_CCM_16:
  429                 txform = &enc_xform_ccm;
  430                 break;
  431         default:
  432                 CRYPTDEB("invalid cipher");
  433                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  434                 return (EINVAL);
  435         }
  436 
  437         switch (sop->mac) {
  438         case 0:
  439                 thash = NULL;
  440                 break;
  441         case CRYPTO_POLY1305:
  442                 thash = &auth_hash_poly1305;
  443                 break;
  444         case CRYPTO_SHA1_HMAC:
  445                 thash = &auth_hash_hmac_sha1;
  446                 break;
  447         case CRYPTO_SHA2_224_HMAC:
  448                 thash = &auth_hash_hmac_sha2_224;
  449                 break;
  450         case CRYPTO_SHA2_256_HMAC:
  451                 thash = &auth_hash_hmac_sha2_256;
  452                 break;
  453         case CRYPTO_SHA2_384_HMAC:
  454                 thash = &auth_hash_hmac_sha2_384;
  455                 break;
  456         case CRYPTO_SHA2_512_HMAC:
  457                 thash = &auth_hash_hmac_sha2_512;
  458                 break;
  459         case CRYPTO_RIPEMD160_HMAC:
  460                 thash = &auth_hash_hmac_ripemd_160;
  461                 break;
  462 #ifdef COMPAT_FREEBSD12
  463         case CRYPTO_AES_128_NIST_GMAC:
  464         case CRYPTO_AES_192_NIST_GMAC:
  465         case CRYPTO_AES_256_NIST_GMAC:
  466                 /* Should always be paired with GCM. */
  467                 if (sop->cipher != CRYPTO_AES_NIST_GCM_16) {
  468                         CRYPTDEB("GMAC without GCM");
  469                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  470                         return (EINVAL);
  471                 }
  472                 break;
  473 #endif
  474         case CRYPTO_AES_NIST_GMAC:
  475                 switch (sop->mackeylen * 8) {
  476                 case 128:
  477                         thash = &auth_hash_nist_gmac_aes_128;
  478                         break;
  479                 case 192:
  480                         thash = &auth_hash_nist_gmac_aes_192;
  481                         break;
  482                 case 256:
  483                         thash = &auth_hash_nist_gmac_aes_256;
  484                         break;
  485                 default:
  486                         CRYPTDEB("invalid GMAC key length");
  487                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  488                         return (EINVAL);
  489                 }
  490                 break;
  491         case CRYPTO_AES_CCM_CBC_MAC:
  492                 switch (sop->mackeylen) {
  493                 case 16:
  494                         thash = &auth_hash_ccm_cbc_mac_128;
  495                         break;
  496                 case 24:
  497                         thash = &auth_hash_ccm_cbc_mac_192;
  498                         break;
  499                 case 32:
  500                         thash = &auth_hash_ccm_cbc_mac_256;
  501                         break;
  502                 default:
  503                         CRYPTDEB("Invalid CBC MAC key size %d", sop->keylen);
  504                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  505                         return (EINVAL);
  506                 }
  507                 break;
  508         case CRYPTO_SHA1:
  509                 thash = &auth_hash_sha1;
  510                 break;
  511         case CRYPTO_SHA2_224:
  512                 thash = &auth_hash_sha2_224;
  513                 break;
  514         case CRYPTO_SHA2_256:
  515                 thash = &auth_hash_sha2_256;
  516                 break;
  517         case CRYPTO_SHA2_384:
  518                 thash = &auth_hash_sha2_384;
  519                 break;
  520         case CRYPTO_SHA2_512:
  521                 thash = &auth_hash_sha2_512;
  522                 break;
  523 
  524         case CRYPTO_NULL_HMAC:
  525                 thash = &auth_hash_null;
  526                 break;
  527 
  528         case CRYPTO_BLAKE2B:
  529                 thash = &auth_hash_blake2b;
  530                 break;
  531         case CRYPTO_BLAKE2S:
  532                 thash = &auth_hash_blake2s;
  533                 break;
  534 
  535         default:
  536                 CRYPTDEB("invalid mac");
  537                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  538                 return (EINVAL);
  539         }
  540 
  541         if (txform == NULL && thash == NULL) {
  542                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  543                 return (EINVAL);
  544         }
  545 
  546         memset(&csp, 0, sizeof(csp));
  547         if (use_outputbuffers)
  548                 csp.csp_flags |= CSP_F_SEPARATE_OUTPUT;
  549 
  550         if (sop->cipher == CRYPTO_AES_NIST_GCM_16) {
  551                 switch (sop->mac) {
  552 #ifdef COMPAT_FREEBSD12
  553                 case CRYPTO_AES_128_NIST_GMAC:
  554                 case CRYPTO_AES_192_NIST_GMAC:
  555                 case CRYPTO_AES_256_NIST_GMAC:
  556                         if (sop->keylen != sop->mackeylen) {
  557                                 SDT_PROBE1(opencrypto, dev, ioctl, error,
  558                                     __LINE__);
  559                                 return (EINVAL);
  560                         }
  561                         break;
  562 #endif
  563                 case 0:
  564                         break;
  565                 default:
  566                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  567                         return (EINVAL);
  568                 }
  569                 csp.csp_mode = CSP_MODE_AEAD;
  570         } else if (sop->cipher == CRYPTO_AES_CCM_16) {
  571                 switch (sop->mac) {
  572 #ifdef COMPAT_FREEBSD12
  573                 case CRYPTO_AES_CCM_CBC_MAC:
  574                         if (sop->keylen != sop->mackeylen) {
  575                                 SDT_PROBE1(opencrypto, dev, ioctl, error,
  576                                     __LINE__);
  577                                 return (EINVAL);
  578                         }
  579                         thash = NULL;
  580                         break;
  581 #endif
  582                 case 0:
  583                         break;
  584                 default:
  585                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  586                         return (EINVAL);
  587                 }
  588                 csp.csp_mode = CSP_MODE_AEAD;
  589         } else if (txform != NULL && thash != NULL)
  590                 csp.csp_mode = CSP_MODE_ETA;
  591         else if (txform != NULL)
  592                 csp.csp_mode = CSP_MODE_CIPHER;
  593         else
  594                 csp.csp_mode = CSP_MODE_DIGEST;
  595 
  596         switch (csp.csp_mode) {
  597         case CSP_MODE_AEAD:
  598         case CSP_MODE_ETA:
  599                 if (use_separate_aad)
  600                         csp.csp_flags |= CSP_F_SEPARATE_AAD;
  601                 break;
  602         }
  603 
  604         if (txform != NULL) {
  605                 csp.csp_cipher_alg = txform->type;
  606                 csp.csp_cipher_klen = sop->keylen;
  607                 if (sop->keylen > txform->maxkey ||
  608                     sop->keylen < txform->minkey) {
  609                         CRYPTDEB("invalid cipher parameters");
  610                         error = EINVAL;
  611                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  612                         goto bail;
  613                 }
  614 
  615                 key = malloc(csp.csp_cipher_klen, M_XDATA, M_WAITOK);
  616                 error = copyin(sop->key, key, csp.csp_cipher_klen);
  617                 if (error) {
  618                         CRYPTDEB("invalid key");
  619                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  620                         goto bail;
  621                 }
  622                 csp.csp_cipher_key = key;
  623                 csp.csp_ivlen = txform->ivsize;
  624         }
  625 
  626         if (thash != NULL) {
  627                 csp.csp_auth_alg = thash->type;
  628                 csp.csp_auth_klen = sop->mackeylen;
  629                 if (sop->mackeylen > thash->keysize || sop->mackeylen < 0) {
  630                         CRYPTDEB("invalid mac key length");
  631                         error = EINVAL;
  632                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  633                         goto bail;
  634                 }
  635 
  636                 if (csp.csp_auth_klen != 0) {
  637                         mackey = malloc(csp.csp_auth_klen, M_XDATA, M_WAITOK);
  638                         error = copyin(sop->mackey, mackey, csp.csp_auth_klen);
  639                         if (error) {
  640                                 CRYPTDEB("invalid mac key");
  641                                 SDT_PROBE1(opencrypto, dev, ioctl, error,
  642                                     __LINE__);
  643                                 goto bail;
  644                         }
  645                         csp.csp_auth_key = mackey;
  646                 }
  647 
  648                 if (csp.csp_auth_alg == CRYPTO_AES_NIST_GMAC)
  649                         csp.csp_ivlen = AES_GCM_IV_LEN;
  650                 if (csp.csp_auth_alg == CRYPTO_AES_CCM_CBC_MAC)
  651                         csp.csp_ivlen = AES_CCM_IV_LEN;
  652         }
  653 
  654         crid = sop->crid;
  655         error = checkforsoftware(&crid);
  656         if (error) {
  657                 CRYPTDEB("checkforsoftware");
  658                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  659                 goto bail;
  660         }
  661         error = crypto_newsession(&cses, &csp, crid);
  662         if (error) {
  663                 CRYPTDEB("crypto_newsession");
  664                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  665                 goto bail;
  666         }
  667 
  668         cse = malloc(sizeof(struct csession), M_XDATA, M_WAITOK | M_ZERO);
  669         mtx_init(&cse->lock, "cryptodev", "crypto session lock", MTX_DEF);
  670         refcount_init(&cse->refs, 1);
  671         cse->key = key;
  672         cse->mackey = mackey;
  673         cse->mode = csp.csp_mode;
  674         cse->cses = cses;
  675         cse->txform = txform;
  676         if (thash != NULL)
  677                 cse->hashsize = thash->hashsize;
  678         else if (csp.csp_cipher_alg == CRYPTO_AES_NIST_GCM_16)
  679                 cse->hashsize = AES_GMAC_HASH_LEN;
  680         else if (csp.csp_cipher_alg == CRYPTO_AES_CCM_16)
  681                 cse->hashsize = AES_CBC_MAC_HASH_LEN;
  682         cse->ivsize = csp.csp_ivlen;
  683 
  684         mtx_lock(&fcr->lock);
  685         TAILQ_INSERT_TAIL(&fcr->csessions, cse, next);
  686         cse->ses = fcr->sesn++;
  687         mtx_unlock(&fcr->lock);
  688 
  689         sop->ses = cse->ses;
  690 
  691         /* return hardware/driver id */
  692         sop->crid = crypto_ses2hid(cse->cses);
  693 bail:
  694         if (error) {
  695                 free(key, M_XDATA);
  696                 free(mackey, M_XDATA);
  697         }
  698         return (error);
  699 }
  700 
  701 static struct csession *
  702 cse_find(struct fcrypt *fcr, u_int ses)
  703 {
  704         struct csession *cse;
  705 
  706         mtx_lock(&fcr->lock);
  707         TAILQ_FOREACH(cse, &fcr->csessions, next) {
  708                 if (cse->ses == ses) {
  709                         refcount_acquire(&cse->refs);
  710                         mtx_unlock(&fcr->lock);
  711                         return (cse);
  712                 }
  713         }
  714         mtx_unlock(&fcr->lock);
  715         return (NULL);
  716 }
  717 
  718 static void
  719 cse_free(struct csession *cse)
  720 {
  721 
  722         if (!refcount_release(&cse->refs))
  723                 return;
  724         crypto_freesession(cse->cses);
  725         mtx_destroy(&cse->lock);
  726         if (cse->key)
  727                 free(cse->key, M_XDATA);
  728         if (cse->mackey)
  729                 free(cse->mackey, M_XDATA);
  730         free(cse, M_XDATA);
  731 }
  732 
  733 static bool
  734 cse_delete(struct fcrypt *fcr, u_int ses)
  735 {
  736         struct csession *cse;
  737 
  738         mtx_lock(&fcr->lock);
  739         TAILQ_FOREACH(cse, &fcr->csessions, next) {
  740                 if (cse->ses == ses) {
  741                         TAILQ_REMOVE(&fcr->csessions, cse, next);
  742                         mtx_unlock(&fcr->lock);
  743                         cse_free(cse);
  744                         return (true);
  745                 }
  746         }
  747         mtx_unlock(&fcr->lock);
  748         return (false);
  749 }
  750 
  751 static struct cryptop_data *
  752 cod_alloc(struct csession *cse, size_t aad_len, size_t len)
  753 {
  754         struct cryptop_data *cod;
  755 
  756         cod = malloc(sizeof(struct cryptop_data), M_XDATA, M_WAITOK | M_ZERO);
  757 
  758         cod->cse = cse;
  759         if (crypto_get_params(cse->cses)->csp_flags & CSP_F_SEPARATE_AAD) {
  760                 if (aad_len != 0)
  761                         cod->aad = malloc(aad_len, M_XDATA, M_WAITOK);
  762                 cod->buf = malloc(len, M_XDATA, M_WAITOK);
  763         } else
  764                 cod->buf = malloc(aad_len + len, M_XDATA, M_WAITOK);
  765         if (crypto_get_params(cse->cses)->csp_flags & CSP_F_SEPARATE_OUTPUT)
  766                 cod->obuf = malloc(len, M_XDATA, M_WAITOK);
  767         return (cod);
  768 }
  769 
  770 static void
  771 cod_free(struct cryptop_data *cod)
  772 {
  773 
  774         free(cod->aad, M_XDATA);
  775         free(cod->obuf, M_XDATA);
  776         free(cod->buf, M_XDATA);
  777         free(cod, M_XDATA);
  778 }
  779 
  780 static int
  781 cryptodev_cb(struct cryptop *crp)
  782 {
  783         struct cryptop_data *cod = crp->crp_opaque;
  784 
  785         /*
  786          * Lock to ensure the wakeup() is not missed by the loops
  787          * waiting on cod->done in cryptodev_op() and
  788          * cryptodev_aead().
  789          */
  790         mtx_lock(&cod->cse->lock);
  791         cod->done = true;
  792         mtx_unlock(&cod->cse->lock);
  793         wakeup(cod);
  794         return (0);
  795 }
  796 
  797 static int
  798 cryptodev_op(struct csession *cse, const struct crypt_op *cop)
  799 {
  800         struct cryptop_data *cod = NULL;
  801         struct cryptop *crp = NULL;
  802         char *dst;
  803         int error;
  804 
  805         if (cop->len > 256*1024-4) {
  806                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  807                 return (E2BIG);
  808         }
  809 
  810         if (cse->txform) {
  811                 if (cop->len == 0 || (cop->len % cse->txform->blocksize) != 0) {
  812                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  813                         return (EINVAL);
  814                 }
  815         }
  816 
  817         if (cop->mac && cse->hashsize == 0) {
  818                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  819                 return (EINVAL);
  820         }
  821 
  822         /*
  823          * The COP_F_CIPHER_FIRST flag predates explicit session
  824          * modes, but the only way it was used was for EtA so allow it
  825          * as long as it is consistent with EtA.
  826          */
  827         if (cop->flags & COP_F_CIPHER_FIRST) {
  828                 if (cop->op != COP_ENCRYPT) {
  829                         SDT_PROBE1(opencrypto, dev, ioctl, error,  __LINE__);
  830                         return (EINVAL);
  831                 }
  832         }
  833 
  834         cod = cod_alloc(cse, 0, cop->len + cse->hashsize);
  835         dst = cop->dst;
  836 
  837         crp = crypto_getreq(cse->cses, M_WAITOK);
  838 
  839         error = copyin(cop->src, cod->buf, cop->len);
  840         if (error) {
  841                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  842                 goto bail;
  843         }
  844         crp->crp_payload_start = 0;
  845         crp->crp_payload_length = cop->len;
  846         if (cse->hashsize)
  847                 crp->crp_digest_start = cop->len;
  848 
  849         switch (cse->mode) {
  850         case CSP_MODE_COMPRESS:
  851                 switch (cop->op) {
  852                 case COP_ENCRYPT:
  853                         crp->crp_op = CRYPTO_OP_COMPRESS;
  854                         break;
  855                 case COP_DECRYPT:
  856                         crp->crp_op = CRYPTO_OP_DECOMPRESS;
  857                         break;
  858                 default:
  859                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  860                         error = EINVAL;
  861                         goto bail;
  862                 }
  863                 break;
  864         case CSP_MODE_CIPHER:
  865                 switch (cop->op) {
  866                 case COP_ENCRYPT:
  867                         crp->crp_op = CRYPTO_OP_ENCRYPT;
  868                         break;
  869                 case COP_DECRYPT:
  870                         crp->crp_op = CRYPTO_OP_DECRYPT;
  871                         break;
  872                 default:
  873                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  874                         error = EINVAL;
  875                         goto bail;
  876                 }
  877                 break;
  878         case CSP_MODE_DIGEST:
  879                 switch (cop->op) {
  880                 case 0:
  881                 case COP_ENCRYPT:
  882                 case COP_DECRYPT:
  883                         crp->crp_op = CRYPTO_OP_COMPUTE_DIGEST;
  884                         if (cod->obuf != NULL)
  885                                 crp->crp_digest_start = 0;
  886                         break;
  887                 default:
  888                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  889                         error = EINVAL;
  890                         goto bail;
  891                 }
  892                 break;
  893         case CSP_MODE_ETA:
  894                 switch (cop->op) {
  895                 case COP_ENCRYPT:
  896                         crp->crp_op = CRYPTO_OP_ENCRYPT |
  897                             CRYPTO_OP_COMPUTE_DIGEST;
  898                         break;
  899                 case COP_DECRYPT:
  900                         crp->crp_op = CRYPTO_OP_DECRYPT |
  901                             CRYPTO_OP_VERIFY_DIGEST;
  902                         break;
  903                 default:
  904                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  905                         error = EINVAL;
  906                         goto bail;
  907                 }
  908                 break;
  909         default:
  910                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  911                 error = EINVAL;
  912                 goto bail;
  913         }
  914 
  915         crp->crp_flags = CRYPTO_F_CBIMM | (cop->flags & COP_F_BATCH);
  916         crypto_use_buf(crp, cod->buf, cop->len + cse->hashsize);
  917         if (cod->obuf)
  918                 crypto_use_output_buf(crp, cod->obuf, cop->len + cse->hashsize);
  919         crp->crp_callback = cryptodev_cb;
  920         crp->crp_opaque = cod;
  921 
  922         if (cop->iv) {
  923                 if (cse->ivsize == 0) {
  924                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  925                         error = EINVAL;
  926                         goto bail;
  927                 }
  928                 error = copyin(cop->iv, crp->crp_iv, cse->ivsize);
  929                 if (error) {
  930                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  931                         goto bail;
  932                 }
  933                 crp->crp_flags |= CRYPTO_F_IV_SEPARATE;
  934         } else if (cse->ivsize != 0) {
  935                 crp->crp_iv_start = 0;
  936                 crp->crp_payload_start += cse->ivsize;
  937                 crp->crp_payload_length -= cse->ivsize;
  938                 dst += cse->ivsize;
  939         }
  940 
  941         if (cop->mac != NULL && crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) {
  942                 error = copyin(cop->mac, cod->buf + crp->crp_digest_start,
  943                     cse->hashsize);
  944                 if (error) {
  945                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  946                         goto bail;
  947                 }
  948         }
  949 again:
  950         /*
  951          * Let the dispatch run unlocked, then, interlock against the
  952          * callback before checking if the operation completed and going
  953          * to sleep.  This insures drivers don't inherit our lock which
  954          * results in a lock order reversal between crypto_dispatch forced
  955          * entry and the crypto_done callback into us.
  956          */
  957         error = crypto_dispatch(crp);
  958         if (error != 0) {
  959                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  960                 goto bail;
  961         }
  962 
  963         mtx_lock(&cse->lock);
  964         while (!cod->done)
  965                 mtx_sleep(cod, &cse->lock, PWAIT, "crydev", 0);
  966         mtx_unlock(&cse->lock);
  967 
  968         if (crp->crp_etype == EAGAIN) {
  969                 crp->crp_etype = 0;
  970                 crp->crp_flags &= ~CRYPTO_F_DONE;
  971                 cod->done = false;
  972                 goto again;
  973         }
  974 
  975         if (crp->crp_etype != 0) {
  976                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  977                 error = crp->crp_etype;
  978                 goto bail;
  979         }
  980 
  981         if (cop->dst != NULL) {
  982                 error = copyout(cod->obuf != NULL ? cod->obuf :
  983                     cod->buf + crp->crp_payload_start, dst,
  984                     crp->crp_payload_length);
  985                 if (error) {
  986                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  987                         goto bail;
  988                 }
  989         }
  990 
  991         if (cop->mac != NULL && (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) == 0) {
  992                 error = copyout((cod->obuf != NULL ? cod->obuf : cod->buf) +
  993                     crp->crp_digest_start, cop->mac, cse->hashsize);
  994                 if (error) {
  995                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  996                         goto bail;
  997                 }
  998         }
  999 
 1000 bail:
 1001         crypto_freereq(crp);
 1002         cod_free(cod);
 1003 
 1004         return (error);
 1005 }
 1006 
 1007 static int
 1008 cryptodev_aead(struct csession *cse, struct crypt_aead *caead)
 1009 {
 1010         struct cryptop_data *cod = NULL;
 1011         struct cryptop *crp = NULL;
 1012         char *dst;
 1013         int error;
 1014 
 1015         if (caead->len > 256*1024-4 || caead->aadlen > 256*1024-4) {
 1016                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1017                 return (E2BIG);
 1018         }
 1019 
 1020         if (cse->txform == NULL || cse->hashsize == 0 || caead->tag == NULL ||
 1021             (caead->len % cse->txform->blocksize) != 0) {
 1022                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1023                 return (EINVAL);
 1024         }
 1025 
 1026         /*
 1027          * The COP_F_CIPHER_FIRST flag predates explicit session
 1028          * modes, but the only way it was used was for EtA so allow it
 1029          * as long as it is consistent with EtA.
 1030          */
 1031         if (caead->flags & COP_F_CIPHER_FIRST) {
 1032                 if (caead->op != COP_ENCRYPT) {
 1033                         SDT_PROBE1(opencrypto, dev, ioctl, error,  __LINE__);
 1034                         return (EINVAL);
 1035                 }
 1036         }
 1037 
 1038         cod = cod_alloc(cse, caead->aadlen, caead->len + cse->hashsize);
 1039         dst = caead->dst;
 1040 
 1041         crp = crypto_getreq(cse->cses, M_WAITOK);
 1042 
 1043         if (cod->aad != NULL)
 1044                 error = copyin(caead->aad, cod->aad, caead->aadlen);
 1045         else
 1046                 error = copyin(caead->aad, cod->buf, caead->aadlen);
 1047         if (error) {
 1048                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1049                 goto bail;
 1050         }
 1051         crp->crp_aad = cod->aad;
 1052         crp->crp_aad_start = 0;
 1053         crp->crp_aad_length = caead->aadlen;
 1054 
 1055         if (cod->aad != NULL)
 1056                 crp->crp_payload_start = 0;
 1057         else
 1058                 crp->crp_payload_start = caead->aadlen;
 1059         error = copyin(caead->src, cod->buf + crp->crp_payload_start,
 1060             caead->len);
 1061         if (error) {
 1062                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1063                 goto bail;
 1064         }
 1065         crp->crp_payload_length = caead->len;
 1066         if (caead->op == COP_ENCRYPT && cod->obuf != NULL)
 1067                 crp->crp_digest_start = crp->crp_payload_output_start +
 1068                     caead->len;
 1069         else
 1070                 crp->crp_digest_start = crp->crp_payload_start + caead->len;
 1071 
 1072         switch (cse->mode) {
 1073         case CSP_MODE_AEAD:
 1074         case CSP_MODE_ETA:
 1075                 switch (caead->op) {
 1076                 case COP_ENCRYPT:
 1077                         crp->crp_op = CRYPTO_OP_ENCRYPT |
 1078                             CRYPTO_OP_COMPUTE_DIGEST;
 1079                         break;
 1080                 case COP_DECRYPT:
 1081                         crp->crp_op = CRYPTO_OP_DECRYPT |
 1082                             CRYPTO_OP_VERIFY_DIGEST;
 1083                         break;
 1084                 default:
 1085                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1086                         error = EINVAL;
 1087                         goto bail;
 1088                 }
 1089                 break;
 1090         default:
 1091                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1092                 error = EINVAL;
 1093                 goto bail;
 1094         }
 1095 
 1096         crp->crp_flags = CRYPTO_F_CBIMM | (caead->flags & COP_F_BATCH);
 1097         crypto_use_buf(crp, cod->buf, crp->crp_payload_start + caead->len +
 1098             cse->hashsize);
 1099         if (cod->obuf != NULL)
 1100                 crypto_use_output_buf(crp, cod->obuf, caead->len +
 1101                     cse->hashsize);
 1102         crp->crp_callback = cryptodev_cb;
 1103         crp->crp_opaque = cod;
 1104 
 1105         if (caead->iv) {
 1106                 /*
 1107                  * Permit a 16-byte IV for AES-XTS, but only use the
 1108                  * first 8 bytes as a block number.
 1109                  */
 1110                 if (cse->mode == CSP_MODE_ETA &&
 1111                     caead->ivlen == AES_BLOCK_LEN &&
 1112                     cse->ivsize == AES_XTS_IV_LEN)
 1113                         caead->ivlen = AES_XTS_IV_LEN;
 1114 
 1115                 if (caead->ivlen != cse->ivsize) {
 1116                         error = EINVAL;
 1117                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1118                         goto bail;
 1119                 }
 1120 
 1121                 error = copyin(caead->iv, crp->crp_iv, cse->ivsize);
 1122                 if (error) {
 1123                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1124                         goto bail;
 1125                 }
 1126                 crp->crp_flags |= CRYPTO_F_IV_SEPARATE;
 1127         } else {
 1128                 crp->crp_iv_start = crp->crp_payload_start;
 1129                 crp->crp_payload_start += cse->ivsize;
 1130                 crp->crp_payload_length -= cse->ivsize;
 1131                 dst += cse->ivsize;
 1132         }
 1133 
 1134         if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) {
 1135                 error = copyin(caead->tag, cod->buf + crp->crp_digest_start,
 1136                     cse->hashsize);
 1137                 if (error) {
 1138                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1139                         goto bail;
 1140                 }
 1141         }
 1142 again:
 1143         /*
 1144          * Let the dispatch run unlocked, then, interlock against the
 1145          * callback before checking if the operation completed and going
 1146          * to sleep.  This insures drivers don't inherit our lock which
 1147          * results in a lock order reversal between crypto_dispatch forced
 1148          * entry and the crypto_done callback into us.
 1149          */
 1150         error = crypto_dispatch(crp);
 1151         if (error != 0) {
 1152                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1153                 goto bail;
 1154         }
 1155 
 1156         mtx_lock(&cse->lock);
 1157         while (!cod->done)
 1158                 mtx_sleep(cod, &cse->lock, PWAIT, "crydev", 0);
 1159         mtx_unlock(&cse->lock);
 1160 
 1161         if (crp->crp_etype == EAGAIN) {
 1162                 crp->crp_etype = 0;
 1163                 crp->crp_flags &= ~CRYPTO_F_DONE;
 1164                 cod->done = false;
 1165                 goto again;
 1166         }
 1167 
 1168         if (crp->crp_etype != 0) {
 1169                 error = crp->crp_etype;
 1170                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1171                 goto bail;
 1172         }
 1173 
 1174         if (caead->dst != NULL) {
 1175                 error = copyout(cod->obuf != NULL ? cod->obuf :
 1176                     cod->buf + crp->crp_payload_start, dst,
 1177                     crp->crp_payload_length);
 1178                 if (error) {
 1179                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1180                         goto bail;
 1181                 }
 1182         }
 1183 
 1184         if ((crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) == 0) {
 1185                 error = copyout((cod->obuf != NULL ? cod->obuf : cod->buf) +
 1186                     crp->crp_digest_start, caead->tag, cse->hashsize);
 1187                 if (error) {
 1188                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1189                         goto bail;
 1190                 }
 1191         }
 1192 
 1193 bail:
 1194         crypto_freereq(crp);
 1195         cod_free(cod);
 1196 
 1197         return (error);
 1198 }
 1199 
 1200 static void
 1201 cryptodevkey_cb(struct cryptkop *krp)
 1202 {
 1203 
 1204         wakeup_one(krp);
 1205 }
 1206 
 1207 static int
 1208 cryptodev_key(struct crypt_kop *kop)
 1209 {
 1210         struct cryptkop *krp = NULL;
 1211         int error = EINVAL;
 1212         int in, out, size, i;
 1213 
 1214         if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) {
 1215                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1216                 return (EFBIG);
 1217         }
 1218 
 1219         in = kop->crk_iparams;
 1220         out = kop->crk_oparams;
 1221         switch (kop->crk_op) {
 1222         case CRK_MOD_EXP:
 1223                 if (in == 3 && out == 1)
 1224                         break;
 1225                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1226                 return (EINVAL);
 1227         case CRK_MOD_EXP_CRT:
 1228                 if (in == 6 && out == 1)
 1229                         break;
 1230                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1231                 return (EINVAL);
 1232         case CRK_DSA_SIGN:
 1233                 if (in == 5 && out == 2)
 1234                         break;
 1235                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1236                 return (EINVAL);
 1237         case CRK_DSA_VERIFY:
 1238                 if (in == 7 && out == 0)
 1239                         break;
 1240                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1241                 return (EINVAL);
 1242         case CRK_DH_COMPUTE_KEY:
 1243                 if (in == 3 && out == 1)
 1244                         break;
 1245                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1246                 return (EINVAL);
 1247         default:
 1248                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1249                 return (EINVAL);
 1250         }
 1251 
 1252         krp = malloc(sizeof(*krp), M_XDATA, M_WAITOK | M_ZERO);
 1253         krp->krp_op = kop->crk_op;
 1254         krp->krp_status = kop->crk_status;
 1255         krp->krp_iparams = kop->crk_iparams;
 1256         krp->krp_oparams = kop->crk_oparams;
 1257         krp->krp_crid = kop->crk_crid;
 1258         krp->krp_status = 0;
 1259         krp->krp_callback = cryptodevkey_cb;
 1260 
 1261         for (i = 0; i < CRK_MAXPARAM; i++) {
 1262                 if (kop->crk_param[i].crp_nbits > 65536) {
 1263                         /* Limit is the same as in OpenBSD */
 1264                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1265                         goto fail;
 1266                 }
 1267                 krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits;
 1268         }
 1269         for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) {
 1270                 size = (krp->krp_param[i].crp_nbits + 7) / 8;
 1271                 if (size == 0)
 1272                         continue;
 1273                 krp->krp_param[i].crp_p = malloc(size, M_XDATA, M_WAITOK);
 1274                 if (i >= krp->krp_iparams)
 1275                         continue;
 1276                 error = copyin(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p, size);
 1277                 if (error) {
 1278                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1279                         goto fail;
 1280                 }
 1281         }
 1282 
 1283         error = crypto_kdispatch(krp);
 1284         if (error) {
 1285                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1286                 goto fail;
 1287         }
 1288         error = tsleep(krp, PSOCK, "crydev", 0);
 1289         if (error) {
 1290                 /* XXX can this happen?  if so, how do we recover? */
 1291                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1292                 goto fail;
 1293         }
 1294         
 1295         kop->crk_crid = krp->krp_hid;           /* device that did the work */
 1296         if (krp->krp_status != 0) {
 1297                 error = krp->krp_status;
 1298                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1299                 goto fail;
 1300         }
 1301 
 1302         for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) {
 1303                 size = (krp->krp_param[i].crp_nbits + 7) / 8;
 1304                 if (size == 0)
 1305                         continue;
 1306                 error = copyout(krp->krp_param[i].crp_p, kop->crk_param[i].crp_p, size);
 1307                 if (error) {
 1308                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1309                         goto fail;
 1310                 }
 1311         }
 1312 
 1313 fail:
 1314         if (krp) {
 1315                 kop->crk_status = krp->krp_status;
 1316                 for (i = 0; i < CRK_MAXPARAM; i++) {
 1317                         if (krp->krp_param[i].crp_p)
 1318                                 free(krp->krp_param[i].crp_p, M_XDATA);
 1319                 }
 1320                 free(krp, M_XDATA);
 1321         }
 1322         return (error);
 1323 }
 1324 
 1325 static int
 1326 cryptodev_find(struct crypt_find_op *find)
 1327 {
 1328         device_t dev;
 1329         size_t fnlen = sizeof find->name;
 1330 
 1331         if (find->crid != -1) {
 1332                 dev = crypto_find_device_byhid(find->crid);
 1333                 if (dev == NULL)
 1334                         return (ENOENT);
 1335                 strncpy(find->name, device_get_nameunit(dev), fnlen);
 1336                 find->name[fnlen - 1] = '\x';
 1337         } else {
 1338                 find->name[fnlen - 1] = '\x';
 1339                 find->crid = crypto_find_driver(find->name);
 1340                 if (find->crid == -1)
 1341                         return (ENOENT);
 1342         }
 1343         return (0);
 1344 }
 1345 
 1346 static void
 1347 fcrypt_dtor(void *data)
 1348 {
 1349         struct fcrypt *fcr = data;
 1350         struct csession *cse;
 1351 
 1352         while ((cse = TAILQ_FIRST(&fcr->csessions))) {
 1353                 TAILQ_REMOVE(&fcr->csessions, cse, next);
 1354                 KASSERT(refcount_load(&cse->refs) == 1,
 1355                     ("%s: crypto session %p with %d refs", __func__, cse,
 1356                     refcount_load(&cse->refs)));
 1357                 cse_free(cse);
 1358         }
 1359         mtx_destroy(&fcr->lock);
 1360         free(fcr, M_XDATA);
 1361 }
 1362 
 1363 static int
 1364 crypto_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
 1365 {
 1366         struct fcrypt *fcr;
 1367         int error;
 1368 
 1369         fcr = malloc(sizeof(struct fcrypt), M_XDATA, M_WAITOK | M_ZERO);
 1370         TAILQ_INIT(&fcr->csessions);
 1371         mtx_init(&fcr->lock, "fcrypt", NULL, MTX_DEF);
 1372         error = devfs_set_cdevpriv(fcr, fcrypt_dtor);
 1373         if (error)
 1374                 fcrypt_dtor(fcr);
 1375         return (error);
 1376 }
 1377 
 1378 static int
 1379 crypto_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
 1380     struct thread *td)
 1381 {
 1382         static struct timeval keywarn, featwarn;
 1383         struct fcrypt *fcr;
 1384         struct csession *cse;
 1385         struct session2_op *sop;
 1386         struct crypt_op *cop;
 1387         struct crypt_aead *caead;
 1388         struct crypt_kop *kop;
 1389         uint32_t ses;
 1390         int error = 0;
 1391         union {
 1392                 struct session2_op sopc;
 1393 #ifdef COMPAT_FREEBSD32
 1394                 struct crypt_op copc;
 1395                 struct crypt_aead aeadc;
 1396                 struct crypt_kop kopc;
 1397 #endif
 1398         } thunk;
 1399 #ifdef COMPAT_FREEBSD32
 1400         u_long cmd32;
 1401         void *data32;
 1402 
 1403         cmd32 = 0;
 1404         data32 = NULL;
 1405         switch (cmd) {
 1406         case CIOCGSESSION32:
 1407                 cmd32 = cmd;
 1408                 data32 = data;
 1409                 cmd = CIOCGSESSION;
 1410                 data = (void *)&thunk.sopc;
 1411                 session_op_from_32((struct session_op32 *)data32, &thunk.sopc);
 1412                 break;
 1413         case CIOCGSESSION232:
 1414                 cmd32 = cmd;
 1415                 data32 = data;
 1416                 cmd = CIOCGSESSION2;
 1417                 data = (void *)&thunk.sopc;
 1418                 session2_op_from_32((struct session2_op32 *)data32,
 1419                     &thunk.sopc);
 1420                 break;
 1421         case CIOCCRYPT32:
 1422                 cmd32 = cmd;
 1423                 data32 = data;
 1424                 cmd = CIOCCRYPT;
 1425                 data = (void *)&thunk.copc;
 1426                 crypt_op_from_32((struct crypt_op32 *)data32, &thunk.copc);
 1427                 break;
 1428         case CIOCCRYPTAEAD32:
 1429                 cmd32 = cmd;
 1430                 data32 = data;
 1431                 cmd = CIOCCRYPTAEAD;
 1432                 data = (void *)&thunk.aeadc;
 1433                 crypt_aead_from_32((struct crypt_aead32 *)data32, &thunk.aeadc);
 1434                 break;
 1435         case CIOCKEY32:
 1436         case CIOCKEY232:
 1437                 cmd32 = cmd;
 1438                 data32 = data;
 1439                 if (cmd == CIOCKEY32)
 1440                         cmd = CIOCKEY;
 1441                 else
 1442                         cmd = CIOCKEY2;
 1443                 data = (void *)&thunk.kopc;
 1444                 crypt_kop_from_32((struct crypt_kop32 *)data32, &thunk.kopc);
 1445                 break;
 1446         }
 1447 #endif
 1448 
 1449         devfs_get_cdevpriv((void **)&fcr);
 1450 
 1451         switch (cmd) {
 1452 #ifdef COMPAT_FREEBSD12
 1453         case CRIOGET:
 1454                 /*
 1455                  * NB: This may fail in cases that the old
 1456                  * implementation did not if the current process has
 1457                  * restricted filesystem access (e.g. running in a
 1458                  * jail that does not expose /dev/crypto or in
 1459                  * capability mode).
 1460                  */
 1461                 error = kern_openat(td, AT_FDCWD, "/dev/crypto", UIO_SYSSPACE,
 1462                     O_RDWR, 0);
 1463                 if (error == 0)
 1464                         *(uint32_t *)data = td->td_retval[0];
 1465                 break;
 1466 #endif
 1467         case CIOCGSESSION:
 1468         case CIOCGSESSION2:
 1469                 if (cmd == CIOCGSESSION) {
 1470                         session2_op_from_op((void *)data, &thunk.sopc);
 1471                         sop = &thunk.sopc;
 1472                 } else
 1473                         sop = (struct session2_op *)data;
 1474 
 1475                 error = cse_create(fcr, sop);
 1476                 if (cmd == CIOCGSESSION && error == 0)
 1477                         session2_op_to_op(sop, (void *)data);
 1478                 break;
 1479         case CIOCFSESSION:
 1480                 ses = *(uint32_t *)data;
 1481                 if (!cse_delete(fcr, ses)) {
 1482                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1483                         return (EINVAL);
 1484                 }
 1485                 break;
 1486         case CIOCCRYPT:
 1487                 cop = (struct crypt_op *)data;
 1488                 cse = cse_find(fcr, cop->ses);
 1489                 if (cse == NULL) {
 1490                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1491                         return (EINVAL);
 1492                 }
 1493                 error = cryptodev_op(cse, cop);
 1494                 cse_free(cse);
 1495                 break;
 1496         case CIOCKEY:
 1497         case CIOCKEY2:
 1498                 if (ratecheck(&keywarn, &warninterval))
 1499                         gone_in(14,
 1500                             "Asymmetric crypto operations via /dev/crypto");
 1501 
 1502                 if (!crypto_userasymcrypto) {
 1503                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1504                         return (EPERM);         /* XXX compat? */
 1505                 }
 1506                 kop = (struct crypt_kop *)data;
 1507                 if (cmd == CIOCKEY) {
 1508                         /* NB: crypto core enforces s/w driver use */
 1509                         kop->crk_crid =
 1510                             CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
 1511                 }
 1512                 mtx_lock(&Giant);
 1513                 error = cryptodev_key(kop);
 1514                 mtx_unlock(&Giant);
 1515                 break;
 1516         case CIOCASYMFEAT:
 1517                 if (ratecheck(&featwarn, &warninterval))
 1518                         gone_in(14,
 1519                             "Asymmetric crypto features via /dev/crypto");
 1520 
 1521                 if (!crypto_userasymcrypto) {
 1522                         /*
 1523                          * NB: if user asym crypto operations are
 1524                          * not permitted return "no algorithms"
 1525                          * so well-behaved applications will just
 1526                          * fallback to doing them in software.
 1527                          */
 1528                         *(int *)data = 0;
 1529                 } else {
 1530                         error = crypto_getfeat((int *)data);
 1531                         if (error)
 1532                                 SDT_PROBE1(opencrypto, dev, ioctl, error,
 1533                                     __LINE__);
 1534                 }
 1535                 break;
 1536         case CIOCFINDDEV:
 1537                 error = cryptodev_find((struct crypt_find_op *)data);
 1538                 break;
 1539         case CIOCCRYPTAEAD:
 1540                 caead = (struct crypt_aead *)data;
 1541                 cse = cse_find(fcr, caead->ses);
 1542                 if (cse == NULL) {
 1543                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1544                         return (EINVAL);
 1545                 }
 1546                 error = cryptodev_aead(cse, caead);
 1547                 cse_free(cse);
 1548                 break;
 1549         default:
 1550                 error = EINVAL;
 1551                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1552                 break;
 1553         }
 1554 
 1555 #ifdef COMPAT_FREEBSD32
 1556         switch (cmd32) {
 1557         case CIOCGSESSION32:
 1558                 if (error == 0)
 1559                         session_op_to_32((void *)data, data32);
 1560                 break;
 1561         case CIOCGSESSION232:
 1562                 if (error == 0)
 1563                         session2_op_to_32((void *)data, data32);
 1564                 break;
 1565         case CIOCCRYPT32:
 1566                 if (error == 0)
 1567                         crypt_op_to_32((void *)data, data32);
 1568                 break;
 1569         case CIOCCRYPTAEAD32:
 1570                 if (error == 0)
 1571                         crypt_aead_to_32((void *)data, data32);
 1572                 break;
 1573         case CIOCKEY32:
 1574         case CIOCKEY232:
 1575                 crypt_kop_to_32((void *)data, data32);
 1576                 break;
 1577         }
 1578 #endif
 1579         return (error);
 1580 }
 1581 
 1582 static struct cdevsw crypto_cdevsw = {
 1583         .d_version =    D_VERSION,
 1584         .d_open =       crypto_open,
 1585         .d_ioctl =      crypto_ioctl,
 1586         .d_name =       "crypto",
 1587 };
 1588 static struct cdev *crypto_dev;
 1589 
 1590 /*
 1591  * Initialization code, both for static and dynamic loading.
 1592  */
 1593 static int
 1594 cryptodev_modevent(module_t mod, int type, void *unused)
 1595 {
 1596         switch (type) {
 1597         case MOD_LOAD:
 1598                 if (bootverbose)
 1599                         printf("crypto: <crypto device>\n");
 1600                 crypto_dev = make_dev(&crypto_cdevsw, 0, 
 1601                                       UID_ROOT, GID_WHEEL, 0666,
 1602                                       "crypto");
 1603                 return 0;
 1604         case MOD_UNLOAD:
 1605                 /*XXX disallow if active sessions */
 1606                 destroy_dev(crypto_dev);
 1607                 return 0;
 1608         }
 1609         return EINVAL;
 1610 }
 1611 
 1612 static moduledata_t cryptodev_mod = {
 1613         "cryptodev",
 1614         cryptodev_modevent,
 1615         0
 1616 };
 1617 MODULE_VERSION(cryptodev, 1);
 1618 DECLARE_MODULE(cryptodev, cryptodev_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
 1619 MODULE_DEPEND(cryptodev, crypto, 1, 1, 1);
 1620 MODULE_DEPEND(cryptodev, zlib, 1, 1, 1);

Cache object: 8f27452ad3b0ec44d76535e047da778b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.