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: releng/12.0/sys/opencrypto/cryptodev.c 337940 2018-08-17 00:31:06Z cem $");
   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/sysctl.h>
   51 #include <sys/file.h>
   52 #include <sys/filedesc.h>
   53 #include <sys/errno.h>
   54 #include <sys/uio.h>
   55 #include <sys/random.h>
   56 #include <sys/conf.h>
   57 #include <sys/kernel.h>
   58 #include <sys/module.h>
   59 #include <sys/fcntl.h>
   60 #include <sys/bus.h>
   61 #include <sys/user.h>
   62 #include <sys/sdt.h>
   63 
   64 #include <opencrypto/cryptodev.h>
   65 #include <opencrypto/xform.h>
   66 
   67 SDT_PROVIDER_DECLARE(opencrypto);
   68 
   69 SDT_PROBE_DEFINE1(opencrypto, dev, ioctl, error, "int"/*line number*/);
   70 
   71 #ifdef COMPAT_FREEBSD32
   72 #include <sys/mount.h>
   73 #include <compat/freebsd32/freebsd32.h>
   74 
   75 struct session_op32 {
   76         u_int32_t       cipher;
   77         u_int32_t       mac;
   78         u_int32_t       keylen;
   79         u_int32_t       key;
   80         int             mackeylen;
   81         u_int32_t       mackey;
   82         u_int32_t       ses;
   83 };
   84 
   85 struct session2_op32 {
   86         u_int32_t       cipher;
   87         u_int32_t       mac;
   88         u_int32_t       keylen;
   89         u_int32_t       key;
   90         int             mackeylen;
   91         u_int32_t       mackey;
   92         u_int32_t       ses;
   93         int             crid;
   94         int             pad[4];
   95 };
   96 
   97 struct crypt_op32 {
   98         u_int32_t       ses;
   99         u_int16_t       op;
  100         u_int16_t       flags;
  101         u_int           len;
  102         u_int32_t       src, dst;
  103         u_int32_t       mac;
  104         u_int32_t       iv;
  105 };
  106 
  107 struct crparam32 {
  108         u_int32_t       crp_p;
  109         u_int           crp_nbits;
  110 };
  111 
  112 struct crypt_kop32 {
  113         u_int           crk_op;
  114         u_int           crk_status;
  115         u_short         crk_iparams;
  116         u_short         crk_oparams;
  117         u_int           crk_crid;
  118         struct crparam32        crk_param[CRK_MAXPARAM];
  119 };
  120 
  121 struct cryptotstat32 {
  122         struct timespec32       acc;
  123         struct timespec32       min;
  124         struct timespec32       max;
  125         u_int32_t       count;
  126 };
  127 
  128 struct cryptostats32 {
  129         u_int32_t       cs_ops;
  130         u_int32_t       cs_errs;
  131         u_int32_t       cs_kops;
  132         u_int32_t       cs_kerrs;
  133         u_int32_t       cs_intrs;
  134         u_int32_t       cs_rets;
  135         u_int32_t       cs_blocks;
  136         u_int32_t       cs_kblocks;
  137         struct cryptotstat32 cs_invoke;
  138         struct cryptotstat32 cs_done;
  139         struct cryptotstat32 cs_cb;
  140         struct cryptotstat32 cs_finis;
  141 };
  142 
  143 #define CIOCGSESSION32  _IOWR('c', 101, struct session_op32)
  144 #define CIOCCRYPT32     _IOWR('c', 103, struct crypt_op32)
  145 #define CIOCKEY32       _IOWR('c', 104, struct crypt_kop32)
  146 #define CIOCGSESSION232 _IOWR('c', 106, struct session2_op32)
  147 #define CIOCKEY232      _IOWR('c', 107, struct crypt_kop32)
  148 
  149 static void
  150 session_op_from_32(const struct session_op32 *from, struct session_op *to)
  151 {
  152 
  153         CP(*from, *to, cipher);
  154         CP(*from, *to, mac);
  155         CP(*from, *to, keylen);
  156         PTRIN_CP(*from, *to, key);
  157         CP(*from, *to, mackeylen);
  158         PTRIN_CP(*from, *to, mackey);
  159         CP(*from, *to, ses);
  160 }
  161 
  162 static void
  163 session2_op_from_32(const struct session2_op32 *from, struct session2_op *to)
  164 {
  165 
  166         session_op_from_32((const struct session_op32 *)from,
  167             (struct session_op *)to);
  168         CP(*from, *to, crid);
  169 }
  170 
  171 static void
  172 session_op_to_32(const struct session_op *from, struct session_op32 *to)
  173 {
  174 
  175         CP(*from, *to, cipher);
  176         CP(*from, *to, mac);
  177         CP(*from, *to, keylen);
  178         PTROUT_CP(*from, *to, key);
  179         CP(*from, *to, mackeylen);
  180         PTROUT_CP(*from, *to, mackey);
  181         CP(*from, *to, ses);
  182 }
  183 
  184 static void
  185 session2_op_to_32(const struct session2_op *from, struct session2_op32 *to)
  186 {
  187 
  188         session_op_to_32((const struct session_op *)from,
  189             (struct session_op32 *)to);
  190         CP(*from, *to, crid);
  191 }
  192 
  193 static void
  194 crypt_op_from_32(const struct crypt_op32 *from, struct crypt_op *to)
  195 {
  196 
  197         CP(*from, *to, ses);
  198         CP(*from, *to, op);
  199         CP(*from, *to, flags);
  200         CP(*from, *to, len);
  201         PTRIN_CP(*from, *to, src);
  202         PTRIN_CP(*from, *to, dst);
  203         PTRIN_CP(*from, *to, mac);
  204         PTRIN_CP(*from, *to, iv);
  205 }
  206 
  207 static void
  208 crypt_op_to_32(const struct crypt_op *from, struct crypt_op32 *to)
  209 {
  210 
  211         CP(*from, *to, ses);
  212         CP(*from, *to, op);
  213         CP(*from, *to, flags);
  214         CP(*from, *to, len);
  215         PTROUT_CP(*from, *to, src);
  216         PTROUT_CP(*from, *to, dst);
  217         PTROUT_CP(*from, *to, mac);
  218         PTROUT_CP(*from, *to, iv);
  219 }
  220 
  221 static void
  222 crparam_from_32(const struct crparam32 *from, struct crparam *to)
  223 {
  224 
  225         PTRIN_CP(*from, *to, crp_p);
  226         CP(*from, *to, crp_nbits);
  227 }
  228 
  229 static void
  230 crparam_to_32(const struct crparam *from, struct crparam32 *to)
  231 {
  232 
  233         PTROUT_CP(*from, *to, crp_p);
  234         CP(*from, *to, crp_nbits);
  235 }
  236 
  237 static void
  238 crypt_kop_from_32(const struct crypt_kop32 *from, struct crypt_kop *to)
  239 {
  240         int i;
  241 
  242         CP(*from, *to, crk_op);
  243         CP(*from, *to, crk_status);
  244         CP(*from, *to, crk_iparams);
  245         CP(*from, *to, crk_oparams);
  246         CP(*from, *to, crk_crid);
  247         for (i = 0; i < CRK_MAXPARAM; i++)
  248                 crparam_from_32(&from->crk_param[i], &to->crk_param[i]);
  249 }
  250 
  251 static void
  252 crypt_kop_to_32(const struct crypt_kop *from, struct crypt_kop32 *to)
  253 {
  254         int i;
  255 
  256         CP(*from, *to, crk_op);
  257         CP(*from, *to, crk_status);
  258         CP(*from, *to, crk_iparams);
  259         CP(*from, *to, crk_oparams);
  260         CP(*from, *to, crk_crid);
  261         for (i = 0; i < CRK_MAXPARAM; i++)
  262                 crparam_to_32(&from->crk_param[i], &to->crk_param[i]);
  263 }
  264 #endif
  265 
  266 struct csession {
  267         TAILQ_ENTRY(csession) next;
  268         crypto_session_t cses;
  269         u_int32_t       ses;
  270         struct mtx      lock;           /* for op submission */
  271 
  272         u_int32_t       cipher;
  273         struct enc_xform *txform;
  274         u_int32_t       mac;
  275         struct auth_hash *thash;
  276 
  277         caddr_t         key;
  278         int             keylen;
  279 
  280         caddr_t         mackey;
  281         int             mackeylen;
  282 };
  283 
  284 struct cryptop_data {
  285         struct csession *cse;
  286 
  287         struct iovec    iovec[1];
  288         struct uio      uio;
  289         bool            done;
  290 };
  291 
  292 struct fcrypt {
  293         TAILQ_HEAD(csessionlist, csession) csessions;
  294         int             sesn;
  295 };
  296 
  297 static  int cryptof_ioctl(struct file *, u_long, void *,
  298                     struct ucred *, struct thread *);
  299 static  int cryptof_stat(struct file *, struct stat *,
  300                     struct ucred *, struct thread *);
  301 static  int cryptof_close(struct file *, struct thread *);
  302 static  int cryptof_fill_kinfo(struct file *, struct kinfo_file *,
  303                     struct filedesc *);
  304 
  305 static struct fileops cryptofops = {
  306     .fo_read = invfo_rdwr,
  307     .fo_write = invfo_rdwr,
  308     .fo_truncate = invfo_truncate,
  309     .fo_ioctl = cryptof_ioctl,
  310     .fo_poll = invfo_poll,
  311     .fo_kqfilter = invfo_kqfilter,
  312     .fo_stat = cryptof_stat,
  313     .fo_close = cryptof_close,
  314     .fo_chmod = invfo_chmod,
  315     .fo_chown = invfo_chown,
  316     .fo_sendfile = invfo_sendfile,
  317     .fo_fill_kinfo = cryptof_fill_kinfo,
  318 };
  319 
  320 static struct csession *csefind(struct fcrypt *, u_int);
  321 static int csedelete(struct fcrypt *, struct csession *);
  322 static struct csession *cseadd(struct fcrypt *, struct csession *);
  323 static struct csession *csecreate(struct fcrypt *, crypto_session_t, caddr_t,
  324     u_int64_t, caddr_t, u_int64_t, u_int32_t, u_int32_t, struct enc_xform *,
  325     struct auth_hash *);
  326 static void csefree(struct csession *);
  327 
  328 static  int cryptodev_op(struct csession *, struct crypt_op *,
  329                         struct ucred *, struct thread *td);
  330 static  int cryptodev_aead(struct csession *, struct crypt_aead *,
  331                         struct ucred *, struct thread *);
  332 static  int cryptodev_key(struct crypt_kop *);
  333 static  int cryptodev_find(struct crypt_find_op *);
  334 
  335 /*
  336  * Check a crypto identifier to see if it requested
  337  * a software device/driver.  This can be done either
  338  * by device name/class or through search constraints.
  339  */
  340 static int
  341 checkforsoftware(int *cridp)
  342 {
  343         int crid;
  344 
  345         crid = *cridp;
  346 
  347         if (!crypto_devallowsoft) {
  348                 if (crid & CRYPTOCAP_F_SOFTWARE) {
  349                         if (crid & CRYPTOCAP_F_HARDWARE) {
  350                                 *cridp = CRYPTOCAP_F_HARDWARE;
  351                                 return 0;
  352                         }
  353                         return EINVAL;
  354                 }
  355                 if ((crid & CRYPTOCAP_F_HARDWARE) == 0 &&
  356                     (crypto_getcaps(crid) & CRYPTOCAP_F_HARDWARE) == 0)
  357                         return EINVAL;
  358         }
  359         return 0;
  360 }
  361 
  362 /* ARGSUSED */
  363 static int
  364 cryptof_ioctl(
  365         struct file *fp,
  366         u_long cmd,
  367         void *data,
  368         struct ucred *active_cred,
  369         struct thread *td)
  370 {
  371 #define SES2(p) ((struct session2_op *)p)
  372         struct cryptoini cria, crie;
  373         struct fcrypt *fcr = fp->f_data;
  374         struct csession *cse;
  375         struct session_op *sop;
  376         struct crypt_op *cop;
  377         struct crypt_aead *caead;
  378         struct enc_xform *txform = NULL;
  379         struct auth_hash *thash = NULL;
  380         struct crypt_kop *kop;
  381         crypto_session_t cses;
  382         u_int32_t ses;
  383         int error = 0, crid;
  384 #ifdef COMPAT_FREEBSD32
  385         struct session2_op sopc;
  386         struct crypt_op copc;
  387         struct crypt_kop kopc;
  388 #endif
  389 
  390         switch (cmd) {
  391         case CIOCGSESSION:
  392         case CIOCGSESSION2:
  393 #ifdef COMPAT_FREEBSD32
  394         case CIOCGSESSION32:
  395         case CIOCGSESSION232:
  396                 if (cmd == CIOCGSESSION32) {
  397                         session_op_from_32(data, (struct session_op *)&sopc);
  398                         sop = (struct session_op *)&sopc;
  399                 } else if (cmd == CIOCGSESSION232) {
  400                         session2_op_from_32(data, &sopc);
  401                         sop = (struct session_op *)&sopc;
  402                 } else
  403 #endif
  404                         sop = (struct session_op *)data;
  405                 switch (sop->cipher) {
  406                 case 0:
  407                         break;
  408                 case CRYPTO_DES_CBC:
  409                         txform = &enc_xform_des;
  410                         break;
  411                 case CRYPTO_3DES_CBC:
  412                         txform = &enc_xform_3des;
  413                         break;
  414                 case CRYPTO_BLF_CBC:
  415                         txform = &enc_xform_blf;
  416                         break;
  417                 case CRYPTO_CAST_CBC:
  418                         txform = &enc_xform_cast5;
  419                         break;
  420                 case CRYPTO_SKIPJACK_CBC:
  421                         txform = &enc_xform_skipjack;
  422                         break;
  423                 case CRYPTO_AES_CBC:
  424                         txform = &enc_xform_rijndael128;
  425                         break;
  426                 case CRYPTO_AES_XTS:
  427                         txform = &enc_xform_aes_xts;
  428                         break;
  429                 case CRYPTO_NULL_CBC:
  430                         txform = &enc_xform_null;
  431                         break;
  432                 case CRYPTO_ARC4:
  433                         txform = &enc_xform_arc4;
  434                         break;
  435                 case CRYPTO_CAMELLIA_CBC:
  436                         txform = &enc_xform_camellia;
  437                         break;
  438                 case CRYPTO_AES_ICM:
  439                         txform = &enc_xform_aes_icm;
  440                         break;
  441                 case CRYPTO_AES_NIST_GCM_16:
  442                         txform = &enc_xform_aes_nist_gcm;
  443                         break;
  444                 case CRYPTO_CHACHA20:
  445                         txform = &enc_xform_chacha20;
  446                         break;
  447 
  448                 default:
  449                         CRYPTDEB("invalid cipher");
  450                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  451                         return (EINVAL);
  452                 }
  453 
  454                 switch (sop->mac) {
  455                 case 0:
  456                         break;
  457                 case CRYPTO_MD5_HMAC:
  458                         thash = &auth_hash_hmac_md5;
  459                         break;
  460                 case CRYPTO_POLY1305:
  461                         thash = &auth_hash_poly1305;
  462                         break;
  463                 case CRYPTO_SHA1_HMAC:
  464                         thash = &auth_hash_hmac_sha1;
  465                         break;
  466                 case CRYPTO_SHA2_224_HMAC:
  467                         thash = &auth_hash_hmac_sha2_224;
  468                         break;
  469                 case CRYPTO_SHA2_256_HMAC:
  470                         thash = &auth_hash_hmac_sha2_256;
  471                         break;
  472                 case CRYPTO_SHA2_384_HMAC:
  473                         thash = &auth_hash_hmac_sha2_384;
  474                         break;
  475                 case CRYPTO_SHA2_512_HMAC:
  476                         thash = &auth_hash_hmac_sha2_512;
  477                         break;
  478                 case CRYPTO_RIPEMD160_HMAC:
  479                         thash = &auth_hash_hmac_ripemd_160;
  480                         break;
  481                 case CRYPTO_AES_128_NIST_GMAC:
  482                         thash = &auth_hash_nist_gmac_aes_128;
  483                         break;
  484                 case CRYPTO_AES_192_NIST_GMAC:
  485                         thash = &auth_hash_nist_gmac_aes_192;
  486                         break;
  487                 case CRYPTO_AES_256_NIST_GMAC:
  488                         thash = &auth_hash_nist_gmac_aes_256;
  489                         break;
  490 
  491 #ifdef notdef
  492                 case CRYPTO_MD5:
  493                         thash = &auth_hash_md5;
  494                         break;
  495 #endif
  496                 case CRYPTO_SHA1:
  497                         thash = &auth_hash_sha1;
  498                         break;
  499                 case CRYPTO_SHA2_224:
  500                         thash = &auth_hash_sha2_224;
  501                         break;
  502                 case CRYPTO_SHA2_256:
  503                         thash = &auth_hash_sha2_256;
  504                         break;
  505                 case CRYPTO_SHA2_384:
  506                         thash = &auth_hash_sha2_384;
  507                         break;
  508                 case CRYPTO_SHA2_512:
  509                         thash = &auth_hash_sha2_512;
  510                         break;
  511 
  512                 case CRYPTO_NULL_HMAC:
  513                         thash = &auth_hash_null;
  514                         break;
  515 
  516                 case CRYPTO_BLAKE2B:
  517                         thash = &auth_hash_blake2b;
  518                         break;
  519                 case CRYPTO_BLAKE2S:
  520                         thash = &auth_hash_blake2s;
  521                         break;
  522 
  523                 default:
  524                         CRYPTDEB("invalid mac");
  525                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  526                         return (EINVAL);
  527                 }
  528 
  529                 bzero(&crie, sizeof(crie));
  530                 bzero(&cria, sizeof(cria));
  531 
  532                 if (txform) {
  533                         crie.cri_alg = txform->type;
  534                         crie.cri_klen = sop->keylen * 8;
  535                         if (sop->keylen > txform->maxkey ||
  536                             sop->keylen < txform->minkey) {
  537                                 CRYPTDEB("invalid cipher parameters");
  538                                 error = EINVAL;
  539                                 SDT_PROBE1(opencrypto, dev, ioctl, error,
  540                                     __LINE__);
  541                                 goto bail;
  542                         }
  543 
  544                         crie.cri_key = malloc(crie.cri_klen / 8,
  545                             M_XDATA, M_WAITOK);
  546                         if ((error = copyin(sop->key, crie.cri_key,
  547                             crie.cri_klen / 8))) {
  548                                 CRYPTDEB("invalid key");
  549                                 SDT_PROBE1(opencrypto, dev, ioctl, error,
  550                                     __LINE__);
  551                                 goto bail;
  552                         }
  553                         if (thash)
  554                                 crie.cri_next = &cria;
  555                 }
  556 
  557                 if (thash) {
  558                         cria.cri_alg = thash->type;
  559                         cria.cri_klen = sop->mackeylen * 8;
  560                         if (thash->keysize != 0 &&
  561                             sop->mackeylen > thash->keysize) {
  562                                 CRYPTDEB("invalid mac key length");
  563                                 error = EINVAL;
  564                                 SDT_PROBE1(opencrypto, dev, ioctl, error,
  565                                     __LINE__);
  566                                 goto bail;
  567                         }
  568 
  569                         if (cria.cri_klen) {
  570                                 cria.cri_key = malloc(cria.cri_klen / 8,
  571                                     M_XDATA, M_WAITOK);
  572                                 if ((error = copyin(sop->mackey, cria.cri_key,
  573                                     cria.cri_klen / 8))) {
  574                                         CRYPTDEB("invalid mac key");
  575                                         SDT_PROBE1(opencrypto, dev, ioctl,
  576                                             error, __LINE__);
  577                                         goto bail;
  578                                 }
  579                         }
  580                 }
  581 
  582                 /* NB: CIOCGSESSION2 has the crid */
  583                 if (cmd == CIOCGSESSION2
  584 #ifdef COMPAT_FREEBSD32
  585                     || cmd == CIOCGSESSION232
  586 #endif
  587                         ) {
  588                         crid = SES2(sop)->crid;
  589                         error = checkforsoftware(&crid);
  590                         if (error) {
  591                                 CRYPTDEB("checkforsoftware");
  592                                 SDT_PROBE1(opencrypto, dev, ioctl, error,
  593                                     __LINE__);
  594                                 goto bail;
  595                         }
  596                 } else
  597                         crid = CRYPTOCAP_F_HARDWARE;
  598                 error = crypto_newsession(&cses, (txform ? &crie : &cria), crid);
  599                 if (error) {
  600                         CRYPTDEB("crypto_newsession");
  601                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  602                         goto bail;
  603                 }
  604 
  605                 cse = csecreate(fcr, cses, crie.cri_key, crie.cri_klen,
  606                     cria.cri_key, cria.cri_klen, sop->cipher, sop->mac, txform,
  607                     thash);
  608 
  609                 if (cse == NULL) {
  610                         crypto_freesession(cses);
  611                         error = EINVAL;
  612                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  613                         CRYPTDEB("csecreate");
  614                         goto bail;
  615                 }
  616                 sop->ses = cse->ses;
  617                 if (cmd == CIOCGSESSION2
  618 #ifdef COMPAT_FREEBSD32
  619                     || cmd == CIOCGSESSION232
  620 #endif
  621                     ) {
  622                         /* return hardware/driver id */
  623                         SES2(sop)->crid = crypto_ses2hid(cse->cses);
  624                 }
  625 bail:
  626                 if (error) {
  627                         if (crie.cri_key)
  628                                 free(crie.cri_key, M_XDATA);
  629                         if (cria.cri_key)
  630                                 free(cria.cri_key, M_XDATA);
  631                 }
  632 #ifdef COMPAT_FREEBSD32
  633                 else {
  634                         if (cmd == CIOCGSESSION32)
  635                                 session_op_to_32(sop, data);
  636                         else if (cmd == CIOCGSESSION232)
  637                                 session2_op_to_32((struct session2_op *)sop,
  638                                     data);
  639                 }
  640 #endif
  641                 break;
  642         case CIOCFSESSION:
  643                 ses = *(u_int32_t *)data;
  644                 cse = csefind(fcr, ses);
  645                 if (cse == NULL) {
  646                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  647                         return (EINVAL);
  648                 }
  649                 csedelete(fcr, cse);
  650                 csefree(cse);
  651                 break;
  652         case CIOCCRYPT:
  653 #ifdef COMPAT_FREEBSD32
  654         case CIOCCRYPT32:
  655                 if (cmd == CIOCCRYPT32) {
  656                         cop = &copc;
  657                         crypt_op_from_32(data, cop);
  658                 } else
  659 #endif
  660                         cop = (struct crypt_op *)data;
  661                 cse = csefind(fcr, cop->ses);
  662                 if (cse == NULL) {
  663                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  664                         return (EINVAL);
  665                 }
  666                 error = cryptodev_op(cse, cop, active_cred, td);
  667 #ifdef COMPAT_FREEBSD32
  668                 if (error == 0 && cmd == CIOCCRYPT32)
  669                         crypt_op_to_32(cop, data);
  670 #endif
  671                 break;
  672         case CIOCKEY:
  673         case CIOCKEY2:
  674 #ifdef COMPAT_FREEBSD32
  675         case CIOCKEY32:
  676         case CIOCKEY232:
  677 #endif
  678                 if (!crypto_userasymcrypto) {
  679                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  680                         return (EPERM);         /* XXX compat? */
  681                 }
  682 #ifdef COMPAT_FREEBSD32
  683                 if (cmd == CIOCKEY32 || cmd == CIOCKEY232) {
  684                         kop = &kopc;
  685                         crypt_kop_from_32(data, kop);
  686                 } else
  687 #endif
  688                         kop = (struct crypt_kop *)data;
  689                 if (cmd == CIOCKEY
  690 #ifdef COMPAT_FREEBSD32
  691                     || cmd == CIOCKEY32
  692 #endif
  693                     ) {
  694                         /* NB: crypto core enforces s/w driver use */
  695                         kop->crk_crid =
  696                             CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
  697                 }
  698                 mtx_lock(&Giant);
  699                 error = cryptodev_key(kop);
  700                 mtx_unlock(&Giant);
  701 #ifdef COMPAT_FREEBSD32
  702                 if (cmd == CIOCKEY32 || cmd == CIOCKEY232)
  703                         crypt_kop_to_32(kop, data);
  704 #endif
  705                 break;
  706         case CIOCASYMFEAT:
  707                 if (!crypto_userasymcrypto) {
  708                         /*
  709                          * NB: if user asym crypto operations are
  710                          * not permitted return "no algorithms"
  711                          * so well-behaved applications will just
  712                          * fallback to doing them in software.
  713                          */
  714                         *(int *)data = 0;
  715                 } else {
  716                         error = crypto_getfeat((int *)data);
  717                         if (error)
  718                                 SDT_PROBE1(opencrypto, dev, ioctl, error,
  719                                     __LINE__);
  720                 }
  721                 break;
  722         case CIOCFINDDEV:
  723                 error = cryptodev_find((struct crypt_find_op *)data);
  724                 break;
  725         case CIOCCRYPTAEAD:
  726                 caead = (struct crypt_aead *)data;
  727                 cse = csefind(fcr, caead->ses);
  728                 if (cse == NULL) {
  729                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  730                         return (EINVAL);
  731                 }
  732                 error = cryptodev_aead(cse, caead, active_cred, td);
  733                 break;
  734         default:
  735                 error = EINVAL;
  736                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  737                 break;
  738         }
  739         return (error);
  740 #undef SES2
  741 }
  742 
  743 static int cryptodev_cb(struct cryptop *);
  744 
  745 static struct cryptop_data *
  746 cod_alloc(struct csession *cse, size_t len, struct thread *td)
  747 {
  748         struct cryptop_data *cod;
  749         struct uio *uio;
  750 
  751         cod = malloc(sizeof(struct cryptop_data), M_XDATA, M_WAITOK | M_ZERO);
  752 
  753         cod->cse = cse;
  754         uio = &cod->uio;
  755         uio->uio_iov = cod->iovec;
  756         uio->uio_iovcnt = 1;
  757         uio->uio_resid = len;
  758         uio->uio_segflg = UIO_SYSSPACE;
  759         uio->uio_rw = UIO_WRITE;
  760         uio->uio_td = td;
  761         uio->uio_iov[0].iov_len = len;
  762         uio->uio_iov[0].iov_base = malloc(len, M_XDATA, M_WAITOK);
  763         return (cod);
  764 }
  765 
  766 static void
  767 cod_free(struct cryptop_data *cod)
  768 {
  769 
  770         free(cod->uio.uio_iov[0].iov_base, M_XDATA);
  771         free(cod, M_XDATA);
  772 }
  773 
  774 static int
  775 cryptodev_op(
  776         struct csession *cse,
  777         struct crypt_op *cop,
  778         struct ucred *active_cred,
  779         struct thread *td)
  780 {
  781         struct cryptop_data *cod = NULL;
  782         struct cryptop *crp = NULL;
  783         struct cryptodesc *crde = NULL, *crda = NULL;
  784         int error;
  785 
  786         if (cop->len > 256*1024-4) {
  787                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  788                 return (E2BIG);
  789         }
  790 
  791         if (cse->txform) {
  792                 if (cop->len == 0 || (cop->len % cse->txform->blocksize) != 0) {
  793                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  794                         return (EINVAL);
  795                 }
  796         }
  797 
  798         if (cse->thash)
  799                 cod = cod_alloc(cse, cop->len + cse->thash->hashsize, td);
  800         else
  801                 cod = cod_alloc(cse, cop->len, td);
  802 
  803         crp = crypto_getreq((cse->txform != NULL) + (cse->thash != NULL));
  804         if (crp == NULL) {
  805                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  806                 error = ENOMEM;
  807                 goto bail;
  808         }
  809 
  810         if (cse->thash && cse->txform) {
  811                 if (cop->flags & COP_F_CIPHER_FIRST) {
  812                         crde = crp->crp_desc;
  813                         crda = crde->crd_next;
  814                 } else {
  815                         crda = crp->crp_desc;
  816                         crde = crda->crd_next;
  817                 }
  818         } else if (cse->thash) {
  819                 crda = crp->crp_desc;
  820         } else if (cse->txform) {
  821                 crde = crp->crp_desc;
  822         } else {
  823                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  824                 error = EINVAL;
  825                 goto bail;
  826         }
  827 
  828         if ((error = copyin(cop->src, cod->uio.uio_iov[0].iov_base,
  829             cop->len))) {
  830                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  831                 goto bail;
  832         }
  833 
  834         if (crda) {
  835                 crda->crd_skip = 0;
  836                 crda->crd_len = cop->len;
  837                 crda->crd_inject = cop->len;
  838 
  839                 crda->crd_alg = cse->mac;
  840                 crda->crd_key = cse->mackey;
  841                 crda->crd_klen = cse->mackeylen * 8;
  842         }
  843 
  844         if (crde) {
  845                 if (cop->op == COP_ENCRYPT)
  846                         crde->crd_flags |= CRD_F_ENCRYPT;
  847                 else
  848                         crde->crd_flags &= ~CRD_F_ENCRYPT;
  849                 crde->crd_len = cop->len;
  850                 crde->crd_inject = 0;
  851 
  852                 crde->crd_alg = cse->cipher;
  853                 crde->crd_key = cse->key;
  854                 crde->crd_klen = cse->keylen * 8;
  855         }
  856 
  857         crp->crp_ilen = cop->len;
  858         crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM
  859                        | (cop->flags & COP_F_BATCH);
  860         crp->crp_uio = &cod->uio;
  861         crp->crp_callback = cryptodev_cb;
  862         crp->crp_session = cse->cses;
  863         crp->crp_opaque = cod;
  864 
  865         if (cop->iv) {
  866                 if (crde == NULL) {
  867                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  868                         error = EINVAL;
  869                         goto bail;
  870                 }
  871                 if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
  872                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  873                         error = EINVAL;
  874                         goto bail;
  875                 }
  876                 if ((error = copyin(cop->iv, crde->crd_iv,
  877                     cse->txform->ivsize))) {
  878                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  879                         goto bail;
  880                 }
  881                 crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
  882                 crde->crd_skip = 0;
  883         } else if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
  884                 crde->crd_skip = 0;
  885         } else if (crde) {
  886                 crde->crd_flags |= CRD_F_IV_PRESENT;
  887                 crde->crd_skip = cse->txform->ivsize;
  888                 crde->crd_len -= cse->txform->ivsize;
  889         }
  890 
  891         if (cop->mac && crda == NULL) {
  892                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  893                 error = EINVAL;
  894                 goto bail;
  895         }
  896 
  897 again:
  898         /*
  899          * Let the dispatch run unlocked, then, interlock against the
  900          * callback before checking if the operation completed and going
  901          * to sleep.  This insures drivers don't inherit our lock which
  902          * results in a lock order reversal between crypto_dispatch forced
  903          * entry and the crypto_done callback into us.
  904          */
  905         error = crypto_dispatch(crp);
  906         if (error != 0) {
  907                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  908                 goto bail;
  909         }
  910 
  911         mtx_lock(&cse->lock);
  912         while (!cod->done)
  913                 mtx_sleep(cod, &cse->lock, PWAIT, "crydev", 0);
  914         mtx_unlock(&cse->lock);
  915 
  916         if (crp->crp_etype == EAGAIN) {
  917                 crp->crp_etype = 0;
  918                 crp->crp_flags &= ~CRYPTO_F_DONE;
  919                 cod->done = false;
  920                 goto again;
  921         }
  922 
  923         if (crp->crp_etype != 0) {
  924                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  925                 error = crp->crp_etype;
  926                 goto bail;
  927         }
  928 
  929         if (cop->dst &&
  930             (error = copyout(cod->uio.uio_iov[0].iov_base, cop->dst,
  931             cop->len))) {
  932                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  933                 goto bail;
  934         }
  935 
  936         if (cop->mac &&
  937             (error = copyout((caddr_t)cod->uio.uio_iov[0].iov_base + cop->len,
  938             cop->mac, cse->thash->hashsize))) {
  939                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  940                 goto bail;
  941         }
  942 
  943 bail:
  944         if (crp)
  945                 crypto_freereq(crp);
  946         if (cod)
  947                 cod_free(cod);
  948 
  949         return (error);
  950 }
  951 
  952 static int
  953 cryptodev_aead(
  954         struct csession *cse,
  955         struct crypt_aead *caead,
  956         struct ucred *active_cred,
  957         struct thread *td)
  958 {
  959         struct cryptop_data *cod = NULL;
  960         struct cryptop *crp = NULL;
  961         struct cryptodesc *crde = NULL, *crda = NULL;
  962         int error;
  963 
  964         if (caead->len > 256*1024-4 || caead->aadlen > 256*1024-4) {
  965                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  966                 return (E2BIG);
  967         }
  968 
  969         if (cse->txform == NULL || cse->thash == NULL || caead->tag == NULL ||
  970             (caead->len % cse->txform->blocksize) != 0) {
  971                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  972                 return (EINVAL);
  973         }
  974 
  975         cod = cod_alloc(cse, caead->aadlen + caead->len + cse->thash->hashsize,
  976             td);
  977 
  978         crp = crypto_getreq(2);
  979         if (crp == NULL) {
  980                 error = ENOMEM;
  981                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  982                 goto bail;
  983         }
  984 
  985         if (caead->flags & COP_F_CIPHER_FIRST) {
  986                 crde = crp->crp_desc;
  987                 crda = crde->crd_next;
  988         } else {
  989                 crda = crp->crp_desc;
  990                 crde = crda->crd_next;
  991         }
  992 
  993         if ((error = copyin(caead->aad, cod->uio.uio_iov[0].iov_base,
  994             caead->aadlen))) {
  995                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
  996                 goto bail;
  997         }
  998 
  999         if ((error = copyin(caead->src, (char *)cod->uio.uio_iov[0].iov_base +
 1000             caead->aadlen, caead->len))) {
 1001                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1002                 goto bail;
 1003         }
 1004 
 1005         /*
 1006          * For GCM, crd_len covers only the AAD.  For other ciphers
 1007          * chained with an HMAC, crd_len covers both the AAD and the
 1008          * cipher text.
 1009          */
 1010         crda->crd_skip = 0;
 1011         if (cse->cipher == CRYPTO_AES_NIST_GCM_16)
 1012                 crda->crd_len = caead->aadlen;
 1013         else
 1014                 crda->crd_len = caead->aadlen + caead->len;
 1015         crda->crd_inject = caead->aadlen + caead->len;
 1016 
 1017         crda->crd_alg = cse->mac;
 1018         crda->crd_key = cse->mackey;
 1019         crda->crd_klen = cse->mackeylen * 8;
 1020 
 1021         if (caead->op == COP_ENCRYPT)
 1022                 crde->crd_flags |= CRD_F_ENCRYPT;
 1023         else
 1024                 crde->crd_flags &= ~CRD_F_ENCRYPT;
 1025         crde->crd_skip = caead->aadlen;
 1026         crde->crd_len = caead->len;
 1027         crde->crd_inject = caead->aadlen;
 1028 
 1029         crde->crd_alg = cse->cipher;
 1030         crde->crd_key = cse->key;
 1031         crde->crd_klen = cse->keylen * 8;
 1032 
 1033         crp->crp_ilen = caead->aadlen + caead->len;
 1034         crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM
 1035                        | (caead->flags & COP_F_BATCH);
 1036         crp->crp_uio = &cod->uio;
 1037         crp->crp_callback = cryptodev_cb;
 1038         crp->crp_session = cse->cses;
 1039         crp->crp_opaque = cod;
 1040 
 1041         if (caead->iv) {
 1042                 if (caead->ivlen > sizeof(crde->crd_iv)) {
 1043                         error = EINVAL;
 1044                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1045                         goto bail;
 1046                 }
 1047 
 1048                 if ((error = copyin(caead->iv, crde->crd_iv, caead->ivlen))) {
 1049                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1050                         goto bail;
 1051                 }
 1052                 crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
 1053         } else {
 1054                 crde->crd_flags |= CRD_F_IV_PRESENT;
 1055                 crde->crd_skip += cse->txform->ivsize;
 1056                 crde->crd_len -= cse->txform->ivsize;
 1057         }
 1058 
 1059         if ((error = copyin(caead->tag, (caddr_t)cod->uio.uio_iov[0].iov_base +
 1060             caead->len + caead->aadlen, cse->thash->hashsize))) {
 1061                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1062                 goto bail;
 1063         }
 1064 again:
 1065         /*
 1066          * Let the dispatch run unlocked, then, interlock against the
 1067          * callback before checking if the operation completed and going
 1068          * to sleep.  This insures drivers don't inherit our lock which
 1069          * results in a lock order reversal between crypto_dispatch forced
 1070          * entry and the crypto_done callback into us.
 1071          */
 1072         error = crypto_dispatch(crp);
 1073         if (error != 0) {
 1074                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1075                 goto bail;
 1076         }
 1077 
 1078         mtx_lock(&cse->lock);
 1079         while (!cod->done)
 1080                 mtx_sleep(cod, &cse->lock, PWAIT, "crydev", 0);
 1081         mtx_unlock(&cse->lock);
 1082 
 1083         if (crp->crp_etype == EAGAIN) {
 1084                 crp->crp_etype = 0;
 1085                 crp->crp_flags &= ~CRYPTO_F_DONE;
 1086                 cod->done = false;
 1087                 goto again;
 1088         }
 1089 
 1090         if (crp->crp_etype != 0) {
 1091                 error = crp->crp_etype;
 1092                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1093                 goto bail;
 1094         }
 1095 
 1096         if (caead->dst && (error = copyout(
 1097             (caddr_t)cod->uio.uio_iov[0].iov_base + caead->aadlen, caead->dst,
 1098             caead->len))) {
 1099                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1100                 goto bail;
 1101         }
 1102 
 1103         if ((error = copyout((caddr_t)cod->uio.uio_iov[0].iov_base +
 1104             caead->aadlen + caead->len, caead->tag, cse->thash->hashsize))) {
 1105                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1106                 goto bail;
 1107         }
 1108 
 1109 bail:
 1110         crypto_freereq(crp);
 1111         if (cod)
 1112                 cod_free(cod);
 1113 
 1114         return (error);
 1115 }
 1116 
 1117 static int
 1118 cryptodev_cb(struct cryptop *crp)
 1119 {
 1120         struct cryptop_data *cod = crp->crp_opaque;
 1121 
 1122         /*
 1123          * Lock to ensure the wakeup() is not missed by the loops
 1124          * waiting on cod->done in cryptodev_op() and
 1125          * cryptodev_aead().
 1126          */
 1127         mtx_lock(&cod->cse->lock);
 1128         cod->done = true;
 1129         mtx_unlock(&cod->cse->lock);
 1130         wakeup(cod);
 1131         return (0);
 1132 }
 1133 
 1134 static int
 1135 cryptodevkey_cb(void *op)
 1136 {
 1137         struct cryptkop *krp = (struct cryptkop *) op;
 1138 
 1139         wakeup_one(krp);
 1140         return (0);
 1141 }
 1142 
 1143 static int
 1144 cryptodev_key(struct crypt_kop *kop)
 1145 {
 1146         struct cryptkop *krp = NULL;
 1147         int error = EINVAL;
 1148         int in, out, size, i;
 1149 
 1150         if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) {
 1151                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1152                 return (EFBIG);
 1153         }
 1154 
 1155         in = kop->crk_iparams;
 1156         out = kop->crk_oparams;
 1157         switch (kop->crk_op) {
 1158         case CRK_MOD_EXP:
 1159                 if (in == 3 && out == 1)
 1160                         break;
 1161                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1162                 return (EINVAL);
 1163         case CRK_MOD_EXP_CRT:
 1164                 if (in == 6 && out == 1)
 1165                         break;
 1166                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1167                 return (EINVAL);
 1168         case CRK_DSA_SIGN:
 1169                 if (in == 5 && out == 2)
 1170                         break;
 1171                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1172                 return (EINVAL);
 1173         case CRK_DSA_VERIFY:
 1174                 if (in == 7 && out == 0)
 1175                         break;
 1176                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1177                 return (EINVAL);
 1178         case CRK_DH_COMPUTE_KEY:
 1179                 if (in == 3 && out == 1)
 1180                         break;
 1181                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1182                 return (EINVAL);
 1183         default:
 1184                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1185                 return (EINVAL);
 1186         }
 1187 
 1188         krp = (struct cryptkop *)malloc(sizeof *krp, M_XDATA, M_WAITOK|M_ZERO);
 1189         if (!krp) {
 1190                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1191                 return (ENOMEM);
 1192         }
 1193         krp->krp_op = kop->crk_op;
 1194         krp->krp_status = kop->crk_status;
 1195         krp->krp_iparams = kop->crk_iparams;
 1196         krp->krp_oparams = kop->crk_oparams;
 1197         krp->krp_crid = kop->crk_crid;
 1198         krp->krp_status = 0;
 1199         krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb;
 1200 
 1201         for (i = 0; i < CRK_MAXPARAM; i++) {
 1202                 if (kop->crk_param[i].crp_nbits > 65536) {
 1203                         /* Limit is the same as in OpenBSD */
 1204                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1205                         goto fail;
 1206                 }
 1207                 krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits;
 1208         }
 1209         for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) {
 1210                 size = (krp->krp_param[i].crp_nbits + 7) / 8;
 1211                 if (size == 0)
 1212                         continue;
 1213                 krp->krp_param[i].crp_p = malloc(size, M_XDATA, M_WAITOK);
 1214                 if (i >= krp->krp_iparams)
 1215                         continue;
 1216                 error = copyin(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p, size);
 1217                 if (error) {
 1218                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1219                         goto fail;
 1220                 }
 1221         }
 1222 
 1223         error = crypto_kdispatch(krp);
 1224         if (error) {
 1225                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1226                 goto fail;
 1227         }
 1228         error = tsleep(krp, PSOCK, "crydev", 0);
 1229         if (error) {
 1230                 /* XXX can this happen?  if so, how do we recover? */
 1231                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1232                 goto fail;
 1233         }
 1234         
 1235         kop->crk_crid = krp->krp_crid;          /* device that did the work */
 1236         if (krp->krp_status != 0) {
 1237                 error = krp->krp_status;
 1238                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1239                 goto fail;
 1240         }
 1241 
 1242         for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) {
 1243                 size = (krp->krp_param[i].crp_nbits + 7) / 8;
 1244                 if (size == 0)
 1245                         continue;
 1246                 error = copyout(krp->krp_param[i].crp_p, kop->crk_param[i].crp_p, size);
 1247                 if (error) {
 1248                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
 1249                         goto fail;
 1250                 }
 1251         }
 1252 
 1253 fail:
 1254         if (krp) {
 1255                 kop->crk_status = krp->krp_status;
 1256                 for (i = 0; i < CRK_MAXPARAM; i++) {
 1257                         if (krp->krp_param[i].crp_p)
 1258                                 free(krp->krp_param[i].crp_p, M_XDATA);
 1259                 }
 1260                 free(krp, M_XDATA);
 1261         }
 1262         return (error);
 1263 }
 1264 
 1265 static int
 1266 cryptodev_find(struct crypt_find_op *find)
 1267 {
 1268         device_t dev;
 1269         size_t fnlen = sizeof find->name;
 1270 
 1271         if (find->crid != -1) {
 1272                 dev = crypto_find_device_byhid(find->crid);
 1273                 if (dev == NULL)
 1274                         return (ENOENT);
 1275                 strncpy(find->name, device_get_nameunit(dev), fnlen);
 1276                 find->name[fnlen - 1] = '\x';
 1277         } else {
 1278                 find->name[fnlen - 1] = '\x';
 1279                 find->crid = crypto_find_driver(find->name);
 1280                 if (find->crid == -1)
 1281                         return (ENOENT);
 1282         }
 1283         return (0);
 1284 }
 1285 
 1286 /* ARGSUSED */
 1287 static int
 1288 cryptof_stat(
 1289         struct file *fp,
 1290         struct stat *sb,
 1291         struct ucred *active_cred,
 1292         struct thread *td)
 1293 {
 1294 
 1295         return (EOPNOTSUPP);
 1296 }
 1297 
 1298 /* ARGSUSED */
 1299 static int
 1300 cryptof_close(struct file *fp, struct thread *td)
 1301 {
 1302         struct fcrypt *fcr = fp->f_data;
 1303         struct csession *cse;
 1304 
 1305         while ((cse = TAILQ_FIRST(&fcr->csessions))) {
 1306                 TAILQ_REMOVE(&fcr->csessions, cse, next);
 1307                 csefree(cse);
 1308         }
 1309         free(fcr, M_XDATA);
 1310         fp->f_data = NULL;
 1311         return 0;
 1312 }
 1313 
 1314 static int
 1315 cryptof_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
 1316 {
 1317 
 1318         kif->kf_type = KF_TYPE_CRYPTO;
 1319         return (0);
 1320 }
 1321 
 1322 static struct csession *
 1323 csefind(struct fcrypt *fcr, u_int ses)
 1324 {
 1325         struct csession *cse;
 1326 
 1327         TAILQ_FOREACH(cse, &fcr->csessions, next)
 1328                 if (cse->ses == ses)
 1329                         return (cse);
 1330         return (NULL);
 1331 }
 1332 
 1333 static int
 1334 csedelete(struct fcrypt *fcr, struct csession *cse_del)
 1335 {
 1336         struct csession *cse;
 1337 
 1338         TAILQ_FOREACH(cse, &fcr->csessions, next) {
 1339                 if (cse == cse_del) {
 1340                         TAILQ_REMOVE(&fcr->csessions, cse, next);
 1341                         return (1);
 1342                 }
 1343         }
 1344         return (0);
 1345 }
 1346         
 1347 static struct csession *
 1348 cseadd(struct fcrypt *fcr, struct csession *cse)
 1349 {
 1350         TAILQ_INSERT_TAIL(&fcr->csessions, cse, next);
 1351         cse->ses = fcr->sesn++;
 1352         return (cse);
 1353 }
 1354 
 1355 struct csession *
 1356 csecreate(struct fcrypt *fcr, crypto_session_t cses, caddr_t key, u_int64_t keylen,
 1357     caddr_t mackey, u_int64_t mackeylen, u_int32_t cipher, u_int32_t mac,
 1358     struct enc_xform *txform, struct auth_hash *thash)
 1359 {
 1360         struct csession *cse;
 1361 
 1362         cse = malloc(sizeof(struct csession), M_XDATA, M_NOWAIT | M_ZERO);
 1363         if (cse == NULL)
 1364                 return NULL;
 1365         mtx_init(&cse->lock, "cryptodev", "crypto session lock", MTX_DEF);
 1366         cse->key = key;
 1367         cse->keylen = keylen/8;
 1368         cse->mackey = mackey;
 1369         cse->mackeylen = mackeylen/8;
 1370         cse->cses = cses;
 1371         cse->cipher = cipher;
 1372         cse->mac = mac;
 1373         cse->txform = txform;
 1374         cse->thash = thash;
 1375         cseadd(fcr, cse);
 1376         return (cse);
 1377 }
 1378 
 1379 static void
 1380 csefree(struct csession *cse)
 1381 {
 1382 
 1383         crypto_freesession(cse->cses);
 1384         mtx_destroy(&cse->lock);
 1385         if (cse->key)
 1386                 free(cse->key, M_XDATA);
 1387         if (cse->mackey)
 1388                 free(cse->mackey, M_XDATA);
 1389         free(cse, M_XDATA);
 1390 }
 1391 
 1392 static int
 1393 cryptoopen(struct cdev *dev, int oflags, int devtype, struct thread *td)
 1394 {
 1395         return (0);
 1396 }
 1397 
 1398 static int
 1399 cryptoread(struct cdev *dev, struct uio *uio, int ioflag)
 1400 {
 1401         return (EIO);
 1402 }
 1403 
 1404 static int
 1405 cryptowrite(struct cdev *dev, struct uio *uio, int ioflag)
 1406 {
 1407         return (EIO);
 1408 }
 1409 
 1410 static int
 1411 cryptoioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
 1412 {
 1413         struct file *f;
 1414         struct fcrypt *fcr;
 1415         int fd, error;
 1416 
 1417         switch (cmd) {
 1418         case CRIOGET:
 1419                 fcr = malloc(sizeof(struct fcrypt), M_XDATA, M_WAITOK);
 1420                 TAILQ_INIT(&fcr->csessions);
 1421                 fcr->sesn = 0;
 1422 
 1423                 error = falloc(td, &f, &fd, 0);
 1424 
 1425                 if (error) {
 1426                         free(fcr, M_XDATA);
 1427                         return (error);
 1428                 }
 1429                 /* falloc automatically provides an extra reference to 'f'. */
 1430                 finit(f, FREAD | FWRITE, DTYPE_CRYPTO, fcr, &cryptofops);
 1431                 *(u_int32_t *)data = fd;
 1432                 fdrop(f, td);
 1433                 break;
 1434         case CRIOFINDDEV:
 1435                 error = cryptodev_find((struct crypt_find_op *)data);
 1436                 break;
 1437         case CRIOASYMFEAT:
 1438                 error = crypto_getfeat((int *)data);
 1439                 break;
 1440         default:
 1441                 error = EINVAL;
 1442                 break;
 1443         }
 1444         return (error);
 1445 }
 1446 
 1447 static struct cdevsw crypto_cdevsw = {
 1448         .d_version =    D_VERSION,
 1449         .d_flags =      D_NEEDGIANT,
 1450         .d_open =       cryptoopen,
 1451         .d_read =       cryptoread,
 1452         .d_write =      cryptowrite,
 1453         .d_ioctl =      cryptoioctl,
 1454         .d_name =       "crypto",
 1455 };
 1456 static struct cdev *crypto_dev;
 1457 
 1458 /*
 1459  * Initialization code, both for static and dynamic loading.
 1460  */
 1461 static int
 1462 cryptodev_modevent(module_t mod, int type, void *unused)
 1463 {
 1464         switch (type) {
 1465         case MOD_LOAD:
 1466                 if (bootverbose)
 1467                         printf("crypto: <crypto device>\n");
 1468                 crypto_dev = make_dev(&crypto_cdevsw, 0, 
 1469                                       UID_ROOT, GID_WHEEL, 0666,
 1470                                       "crypto");
 1471                 return 0;
 1472         case MOD_UNLOAD:
 1473                 /*XXX disallow if active sessions */
 1474                 destroy_dev(crypto_dev);
 1475                 return 0;
 1476         }
 1477         return EINVAL;
 1478 }
 1479 
 1480 static moduledata_t cryptodev_mod = {
 1481         "cryptodev",
 1482         cryptodev_modevent,
 1483         0
 1484 };
 1485 MODULE_VERSION(cryptodev, 1);
 1486 DECLARE_MODULE(cryptodev, cryptodev_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
 1487 MODULE_DEPEND(cryptodev, crypto, 1, 1, 1);
 1488 MODULE_DEPEND(cryptodev, zlib, 1, 1, 1);

Cache object: 83bf71e521d8ed32eb46f74a9a38c0b1


[ 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.