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

Cache object: ef0abb165e225b0299f80ce2a24b9fbe


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