root/crypto/cryptodev.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cryptof_read
  2. cryptof_write
  3. cryptof_ioctl
  4. cryptodev_op
  5. cryptodev_cb
  6. cryptodevkey_cb
  7. cryptodev_key
  8. cryptof_poll
  9. cryptof_kqfilter
  10. cryptof_stat
  11. cryptof_close
  12. cryptoattach
  13. cryptoopen
  14. cryptoclose
  15. cryptoread
  16. cryptowrite
  17. cryptoioctl
  18. cryptopoll
  19. csefind
  20. csedelete
  21. cseadd
  22. csecreate
  23. csefree

    1 /*      $OpenBSD: cryptodev.c,v 1.66 2006/10/25 15:10:25 tedu Exp $     */
    2 
    3 /*
    4  * Copyright (c) 2001 Theo de Raadt
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  *
   10  * 1. Redistributions of source code must retain the above copyright
   11  *   notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *   notice, this list of conditions and the following disclaimer in the
   14  *   documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   26  *
   27  * Effort sponsored in part by the Defense Advanced Research Projects
   28  * Agency (DARPA) and Air Force Research Laboratory, Air Force
   29  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
   30  *
   31  */
   32 
   33 #include <sys/param.h>
   34 #include <sys/systm.h>
   35 #include <sys/malloc.h>
   36 #include <sys/mbuf.h>
   37 #include <sys/sysctl.h>
   38 #include <sys/file.h>
   39 #include <sys/filedesc.h>
   40 #include <sys/errno.h>
   41 #include <dev/rndvar.h>
   42 #include <sys/conf.h>
   43 #include <sys/device.h>
   44 #include <crypto/md5.h>
   45 #include <crypto/sha1.h>
   46 #include <crypto/rmd160.h>
   47 #include <crypto/cast.h>
   48 #include <crypto/skipjack.h>
   49 #include <crypto/blf.h>
   50 #include <crypto/cryptodev.h>
   51 #include <crypto/xform.h>
   52 
   53 extern struct cryptocap *crypto_drivers;
   54 extern int crypto_drivers_num;
   55 
   56 struct csession {
   57         TAILQ_ENTRY(csession) next;
   58         u_int64_t       sid;
   59         u_int32_t       ses;
   60 
   61         u_int32_t       cipher;
   62         struct enc_xform *txform;
   63         u_int32_t       mac;
   64         struct auth_hash *thash;
   65 
   66         caddr_t         key;
   67         int             keylen;
   68         u_char          tmp_iv[EALG_MAX_BLOCK_LEN];
   69 
   70         caddr_t         mackey;
   71         int             mackeylen;
   72         u_char          tmp_mac[CRYPTO_MAX_MAC_LEN];
   73 
   74         struct iovec    iovec[IOV_MAX];
   75         struct uio      uio;
   76         int             error;
   77 };
   78 
   79 struct fcrypt {
   80         TAILQ_HEAD(csessionlist, csession) csessions;
   81         int             sesn;
   82 };
   83 
   84 void    cryptoattach(int);
   85 
   86 int     cryptof_read(struct file *, off_t *, struct uio *, struct ucred *);
   87 int     cryptof_write(struct file *, off_t *, struct uio *, struct ucred *);
   88 int     cryptof_ioctl(struct file *, u_long, caddr_t, struct proc *p);
   89 int     cryptof_poll(struct file *, int, struct proc *);
   90 int     cryptof_kqfilter(struct file *, struct knote *);
   91 int     cryptof_stat(struct file *, struct stat *, struct proc *);
   92 int     cryptof_close(struct file *, struct proc *);
   93 
   94 static struct fileops cryptofops = {
   95     cryptof_read,
   96     cryptof_write,
   97     cryptof_ioctl,
   98     cryptof_poll,
   99     cryptof_kqfilter,
  100     cryptof_stat,
  101     cryptof_close
  102 };
  103 
  104 struct  csession *csefind(struct fcrypt *, u_int);
  105 int     csedelete(struct fcrypt *, struct csession *);
  106 struct  csession *cseadd(struct fcrypt *, struct csession *);
  107 struct  csession *csecreate(struct fcrypt *, u_int64_t, caddr_t, u_int64_t,
  108     caddr_t, u_int64_t, u_int32_t, u_int32_t, struct enc_xform *,
  109     struct auth_hash *);
  110 int     csefree(struct csession *);
  111 
  112 int     cryptodev_op(struct csession *, struct crypt_op *, struct proc *);
  113 int     cryptodev_key(struct crypt_kop *);
  114 int     cryptodev_dokey(struct crypt_kop *kop, struct crparam kvp[]);
  115 
  116 int     cryptodev_cb(struct cryptop *);
  117 int     cryptodevkey_cb(struct cryptkop *);
  118 
  119 int     usercrypto = 1;         /* userland may do crypto requests */
  120 int     userasymcrypto = 1;     /* userland may do asymmetric crypto reqs */
  121 int     cryptodevallowsoft = 0; /* only use hardware crypto */
  122 
  123 /* ARGSUSED */
  124 int
  125 cryptof_read(struct file *fp, off_t *poff, struct uio *uio, struct ucred *cred)
  126 {
  127         return (EIO);
  128 }
  129 
  130 /* ARGSUSED */
  131 int
  132 cryptof_write(struct file *fp, off_t *poff, struct uio *uio, struct ucred *cred)
  133 {
  134         return (EIO);
  135 }
  136 
  137 /* ARGSUSED */
  138 int
  139 cryptof_ioctl(struct file *fp, u_long cmd, caddr_t data, struct proc *p)
  140 {
  141         struct cryptoini cria, crie;
  142         struct fcrypt *fcr = fp->f_data;
  143         struct csession *cse;
  144         struct session_op *sop;
  145         struct crypt_op *cop;
  146         struct enc_xform *txform = NULL;
  147         struct auth_hash *thash = NULL;
  148         u_int64_t sid;
  149         u_int32_t ses;
  150         int error = 0;
  151 
  152         switch (cmd) {
  153         case CIOCGSESSION:
  154                 sop = (struct session_op *)data;
  155                 switch (sop->cipher) {
  156                 case 0:
  157                         break;
  158                 case CRYPTO_DES_CBC:
  159                         txform = &enc_xform_des;
  160                         break;
  161                 case CRYPTO_3DES_CBC:
  162                         txform = &enc_xform_3des;
  163                         break;
  164                 case CRYPTO_BLF_CBC:
  165                         txform = &enc_xform_blf;
  166                         break;
  167                 case CRYPTO_CAST_CBC:
  168                         txform = &enc_xform_cast5;
  169                         break;
  170                 case CRYPTO_SKIPJACK_CBC:
  171                         txform = &enc_xform_skipjack;
  172                         break;
  173                 case CRYPTO_AES_CBC:
  174                         txform = &enc_xform_rijndael128;
  175                         break;
  176                 case CRYPTO_AES_CTR:
  177                         txform = &enc_xform_aes_ctr;
  178                         break;
  179                 case CRYPTO_ARC4:
  180                         txform = &enc_xform_arc4;
  181                         break;
  182                 case CRYPTO_NULL:
  183                         txform = &enc_xform_null;
  184                         break;
  185                 default:
  186                         return (EINVAL);
  187                 }
  188 
  189                 switch (sop->mac) {
  190                 case 0:
  191                         break;
  192 #if 0
  193                 case CRYPTO_MD5_HMAC:
  194                         thash = &auth_hash_hmac_md5_96;
  195                         break;
  196                 case CRYPTO_SHA1_HMAC:
  197                         thash = &auth_hash_hmac_sha1_96;
  198                         break;
  199                 case CRYPTO_RIPEMD160_HMAC:
  200                         thash = &auth_hash_hmac_ripemd_160_96;
  201                         break;
  202                 case CRYPTO_MD5:
  203                         thash = &auth_hash_md5;
  204                         break;
  205                 case CRYPTO_SHA1:
  206                         thash = &auth_hash_sha1;
  207                         break;
  208 #endif
  209                 default:
  210                         return (EINVAL);
  211                 }
  212 
  213                 bzero(&crie, sizeof(crie));
  214                 bzero(&cria, sizeof(cria));
  215 
  216                 if (txform) {
  217                         crie.cri_alg = txform->type;
  218                         crie.cri_klen = sop->keylen * 8;
  219                         if (sop->keylen > txform->maxkey ||
  220                             sop->keylen < txform->minkey) {
  221                                 error = EINVAL;
  222                                 goto bail;
  223                         }
  224 
  225                         MALLOC(crie.cri_key, u_int8_t *,
  226                             crie.cri_klen / 8, M_XDATA, M_WAITOK);
  227                         if ((error = copyin(sop->key, crie.cri_key,
  228                             crie.cri_klen / 8)))
  229                                 goto bail;
  230                         if (thash)
  231                                 crie.cri_next = &cria;
  232                 }
  233 
  234                 if (thash) {
  235                         cria.cri_alg = thash->type;
  236                         cria.cri_klen = sop->mackeylen * 8;
  237                         if (sop->mackeylen != thash->keysize) {
  238                                 error = EINVAL;
  239                                 goto bail;
  240                         }
  241 
  242                         if (cria.cri_klen) {
  243                                 MALLOC(cria.cri_key, u_int8_t *,
  244                                     cria.cri_klen / 8, M_XDATA, M_WAITOK);
  245                                 if ((error = copyin(sop->mackey, cria.cri_key,
  246                                     cria.cri_klen / 8)))
  247                                         goto bail;
  248                         }
  249                 }
  250 
  251                 error = crypto_newsession(&sid, (txform ? &crie : &cria),
  252                     !cryptodevallowsoft);
  253 
  254                 if (error)
  255                         goto bail;
  256 
  257                 cse = csecreate(fcr, sid, crie.cri_key, crie.cri_klen,
  258                     cria.cri_key, cria.cri_klen, sop->cipher, sop->mac, txform,
  259                     thash);
  260 
  261                 if (cse == NULL) {
  262                         crypto_freesession(sid);
  263                         error = EINVAL;
  264                         goto bail;
  265                 }
  266                 sop->ses = cse->ses;
  267 
  268 bail:
  269                 if (error) {
  270                         if (crie.cri_key)
  271                                 FREE(crie.cri_key, M_XDATA);
  272                         if (cria.cri_key)
  273                                 FREE(cria.cri_key, M_XDATA);
  274                 }
  275                 break;
  276         case CIOCFSESSION:
  277                 ses = *(u_int32_t *)data;
  278                 cse = csefind(fcr, ses);
  279                 if (cse == NULL)
  280                         return (EINVAL);
  281                 csedelete(fcr, cse);
  282                 error = csefree(cse);
  283                 break;
  284         case CIOCCRYPT:
  285                 cop = (struct crypt_op *)data;
  286                 cse = csefind(fcr, cop->ses);
  287                 if (cse == NULL)
  288                         return (EINVAL);
  289                 error = cryptodev_op(cse, cop, p);
  290                 break;
  291         case CIOCKEY:
  292                 error = cryptodev_key((struct crypt_kop *)data);
  293                 break;
  294         case CIOCASYMFEAT:
  295                 error = crypto_getfeat((int *)data);
  296                 break;
  297         default:
  298                 error = EINVAL;
  299         }
  300         return (error);
  301 }
  302 
  303 int
  304 cryptodev_op(struct csession *cse, struct crypt_op *cop, struct proc *p)
  305 {
  306         struct cryptop *crp = NULL;
  307         struct cryptodesc *crde = NULL, *crda = NULL;
  308         int i, s, error;
  309         u_int32_t hid;
  310 
  311         if (cop->len > 64*1024-4)
  312                 return (E2BIG);
  313 
  314         if (cse->txform) {
  315                 if (cop->len == 0 || (cop->len % cse->txform->blocksize) != 0)
  316                         return (EINVAL);
  317         }
  318 
  319         bzero(&cse->uio, sizeof(cse->uio));
  320         cse->uio.uio_iovcnt = 1;
  321         cse->uio.uio_resid = 0;
  322         cse->uio.uio_segflg = UIO_SYSSPACE;
  323         cse->uio.uio_rw = UIO_WRITE;
  324         cse->uio.uio_procp = p;
  325         cse->uio.uio_iov = cse->iovec;
  326         bzero(&cse->iovec, sizeof(cse->iovec));
  327         cse->uio.uio_iov[0].iov_len = cop->len;
  328         cse->uio.uio_iov[0].iov_base = malloc(cop->len, M_XDATA, M_WAITOK);
  329         for (i = 0; i < cse->uio.uio_iovcnt; i++)
  330                 cse->uio.uio_resid += cse->uio.uio_iov[0].iov_len;
  331 
  332         /* number of requests, not logical and */
  333         crp = crypto_getreq((cse->txform != NULL) + (cse->thash != NULL));
  334         if (crp == NULL) {
  335                 error = ENOMEM;
  336                 goto bail;
  337         }
  338 
  339         if (cse->thash) {
  340                 crda = crp->crp_desc;
  341                 if (cse->txform)
  342                         crde = crda->crd_next;
  343         } else {
  344                 if (cse->txform)
  345                         crde = crp->crp_desc;
  346                 else {
  347                         error = EINVAL;
  348                         goto bail;
  349                 }
  350         }
  351 
  352         if ((error = copyin(cop->src, cse->uio.uio_iov[0].iov_base, cop->len)))
  353                 goto bail;
  354 
  355         if (crda) {
  356                 crda->crd_skip = 0;
  357                 crda->crd_len = cop->len;
  358                 crda->crd_inject = 0;   /* ??? */
  359 
  360                 crda->crd_alg = cse->mac;
  361                 crda->crd_key = cse->mackey;
  362                 crda->crd_klen = cse->mackeylen * 8;
  363         }
  364 
  365         if (crde) {
  366                 if (cop->op == COP_ENCRYPT)
  367                         crde->crd_flags |= CRD_F_ENCRYPT;
  368                 else
  369                         crde->crd_flags &= ~CRD_F_ENCRYPT;
  370                 crde->crd_len = cop->len;
  371                 crde->crd_inject = 0;
  372 
  373                 crde->crd_alg = cse->cipher;
  374                 crde->crd_key = cse->key;
  375                 crde->crd_klen = cse->keylen * 8;
  376         }
  377 
  378         crp->crp_ilen = cop->len;
  379         crp->crp_buf = (caddr_t)&cse->uio;
  380         crp->crp_callback = cryptodev_cb;
  381         crp->crp_sid = cse->sid;
  382         crp->crp_opaque = cse;
  383 
  384         if (cop->iv) {
  385                 if (crde == NULL) {
  386                         error = EINVAL;
  387                         goto bail;
  388                 }
  389                 if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
  390                         error = EINVAL;
  391                         goto bail;
  392                 }
  393                 if ((error = copyin(cop->iv, cse->tmp_iv, cse->txform->blocksize)))
  394                         goto bail;
  395                 bcopy(cse->tmp_iv, crde->crd_iv, cse->txform->blocksize);
  396                 crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
  397                 crde->crd_skip = 0;
  398         } else if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
  399                 crde->crd_skip = 0;
  400         } else if (crde) {
  401                 crde->crd_flags |= CRD_F_IV_PRESENT;
  402                 crde->crd_skip = cse->txform->blocksize;
  403                 crde->crd_len -= cse->txform->blocksize;
  404         }
  405 
  406         if (cop->mac) {
  407                 if (crda == NULL) {
  408                         error = EINVAL;
  409                         goto bail;
  410                 }
  411                 crp->crp_mac = cse->tmp_mac;
  412         }
  413 
  414         /* try the fast path first */
  415         crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_NOQUEUE;
  416         hid = (crp->crp_sid >> 32) & 0xffffffff;
  417         if (hid >= crypto_drivers_num)
  418                 goto dispatch;
  419         if (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_SOFTWARE)
  420                 goto dispatch;
  421         if (crypto_drivers[hid].cc_process == NULL)
  422                 goto dispatch;
  423         error = crypto_drivers[hid].cc_process(crp);
  424         if (error) {
  425                 /* clear error */
  426                 crp->crp_etype = 0;
  427                 goto dispatch;
  428         }
  429         goto processed;
  430  dispatch:
  431         crp->crp_flags = CRYPTO_F_IOV;
  432         crypto_dispatch(crp);
  433  processed:
  434         s = splnet();
  435         while (!(crp->crp_flags & CRYPTO_F_DONE)) {
  436                 error = tsleep(cse, PSOCK, "crydev", 0);
  437         }
  438         splx(s);
  439         if (error) {
  440                 /* XXX can this happen?  if so, how do we recover? */
  441                 goto bail;
  442         }
  443 
  444         if (cse->error) {
  445                 error = cse->error;
  446                 goto bail;
  447         }
  448         if (crp->crp_etype != 0) {
  449                 error = crp->crp_etype;
  450                 goto bail;
  451         }
  452 
  453 
  454         if (cop->dst &&
  455             (error = copyout(cse->uio.uio_iov[0].iov_base, cop->dst, cop->len)))
  456                 goto bail;
  457 
  458         if (cop->mac &&
  459             (error = copyout(crp->crp_mac, cop->mac, cse->thash->authsize)))
  460                 goto bail;
  461 
  462 bail:
  463         if (crp)
  464                 crypto_freereq(crp);
  465         if (cse->uio.uio_iov[0].iov_base)
  466                 free(cse->uio.uio_iov[0].iov_base, M_XDATA);
  467 
  468         return (error);
  469 }
  470 
  471 int
  472 cryptodev_cb(struct cryptop *crp)
  473 {
  474         struct csession *cse = crp->crp_opaque;
  475 
  476         cse->error = crp->crp_etype;
  477         if (crp->crp_etype == EAGAIN) {
  478                 crp->crp_flags = CRYPTO_F_IOV;
  479                 return crypto_dispatch(crp);
  480         }
  481         wakeup(cse);
  482         return (0);
  483 }
  484 
  485 int
  486 cryptodevkey_cb(struct cryptkop *krp)
  487 {
  488 
  489         wakeup(krp);
  490         return (0);
  491 }
  492 
  493 int
  494 cryptodev_key(struct crypt_kop *kop)
  495 {
  496         struct cryptkop *krp = NULL;
  497         int error = EINVAL;
  498         int in, out, size, i;
  499 
  500         if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) {
  501                 return (EFBIG);
  502         }
  503 
  504         in = kop->crk_iparams;
  505         out = kop->crk_oparams;
  506         switch (kop->crk_op) {
  507         case CRK_MOD_EXP:
  508                 if (in == 3 && out == 1)
  509                         break;
  510                 return (EINVAL);
  511         case CRK_MOD_EXP_CRT:
  512                 if (in == 6 && out == 1)
  513                         break;
  514                 return (EINVAL);
  515         case CRK_DSA_SIGN:
  516                 if (in == 5 && out == 2)
  517                         break;
  518                 return (EINVAL);
  519         case CRK_DSA_VERIFY:
  520                 if (in == 7 && out == 0)
  521                         break;
  522                 return (EINVAL);
  523         case CRK_DH_COMPUTE_KEY:
  524                 if (in == 3 && out == 1)
  525                         break;
  526                 return (EINVAL);
  527         default:
  528                 return (EINVAL);
  529         }
  530 
  531         krp = malloc(sizeof *krp, M_XDATA, M_WAITOK);
  532         bzero(krp, sizeof *krp);
  533         krp->krp_op = kop->crk_op;
  534         krp->krp_status = kop->crk_status;
  535         krp->krp_iparams = kop->crk_iparams;
  536         krp->krp_oparams = kop->crk_oparams;
  537         krp->krp_status = 0;
  538         krp->krp_callback = cryptodevkey_cb;
  539 
  540         for (i = 0; i < CRK_MAXPARAM; i++) {
  541                 krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits;
  542                 if (kop->crk_param[i].crp_nbits > 65536) {
  543                         /* XXX how big do we need to support? */
  544                         goto fail;
  545                 }
  546         }
  547         for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) {
  548                 size = (krp->krp_param[i].crp_nbits + 7) / 8;
  549                 if (size == 0)
  550                         continue;
  551                 krp->krp_param[i].crp_p = malloc(size, M_XDATA, M_WAITOK);
  552                 if (i >= krp->krp_iparams)
  553                         continue;
  554                 error = copyin(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p, size);
  555                 if (error)
  556                         goto fail;
  557         }
  558 
  559         error = crypto_kdispatch(krp);
  560         if (error)
  561                 goto fail;
  562         error = tsleep(krp, PSOCK, "crydev", 0);
  563         if (error) {
  564                 /* XXX can this happen?  if so, how do we recover? */
  565                 goto fail;
  566         }
  567         
  568         if (krp->krp_status != 0) {
  569                 error = krp->krp_status;
  570                 goto fail;
  571         }
  572 
  573         for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) {
  574                 size = (krp->krp_param[i].crp_nbits + 7) / 8;
  575                 if (size == 0)
  576                         continue;
  577                 error = copyout(krp->krp_param[i].crp_p, kop->crk_param[i].crp_p, size);
  578                 if (error)
  579                         goto fail;
  580         }
  581 
  582 fail:
  583         if (krp) {
  584                 kop->crk_status = krp->krp_status;
  585                 for (i = 0; i < CRK_MAXPARAM; i++) {
  586                         if (krp->krp_param[i].crp_p)
  587                                 free(krp->krp_param[i].crp_p, M_XDATA);
  588                 }
  589                 free(krp, M_XDATA);
  590         }
  591         return (error);
  592 }
  593 
  594 /* ARGSUSED */
  595 int
  596 cryptof_poll(struct file *fp, int events, struct proc *p)
  597 {
  598         return (0);
  599 }
  600 
  601 /* ARGSUSED */
  602 int
  603 cryptof_kqfilter(struct file *fp, struct knote *kn)
  604 {
  605         return (0);
  606 }
  607 
  608 /* ARGSUSED */
  609 int
  610 cryptof_stat(struct file *fp, struct stat *sb, struct proc *p)
  611 {
  612         return (EOPNOTSUPP);
  613 }
  614 
  615 /* ARGSUSED */
  616 int
  617 cryptof_close(struct file *fp, struct proc *p)
  618 {
  619         struct fcrypt *fcr = fp->f_data;
  620         struct csession *cse;
  621 
  622         while ((cse = TAILQ_FIRST(&fcr->csessions))) {
  623                 TAILQ_REMOVE(&fcr->csessions, cse, next);
  624                 (void)csefree(cse);
  625         }
  626         FREE(fcr, M_XDATA);
  627         fp->f_data = NULL;
  628         return 0;
  629 }
  630 
  631 void
  632 cryptoattach(int n)
  633 {
  634 }
  635 
  636 int
  637 cryptoopen(dev_t dev, int flag, int mode, struct proc *p)
  638 {
  639         if (usercrypto == 0)
  640                 return (ENXIO);
  641 #ifdef CRYPTO
  642         return (0);
  643 #else
  644         return (ENXIO);
  645 #endif
  646 }
  647 
  648 int
  649 cryptoclose(dev_t dev, int flag, int mode, struct proc *p)
  650 {
  651         return (0);
  652 }
  653 
  654 int
  655 cryptoread(dev_t dev, struct uio *uio, int ioflag)
  656 {
  657         return (EIO);
  658 }
  659 
  660 int
  661 cryptowrite(dev_t dev, struct uio *uio, int ioflag)
  662 {
  663         return (EIO);
  664 }
  665 
  666 int
  667 cryptoioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
  668 {
  669         struct file *f;
  670         struct fcrypt *fcr;
  671         int fd, error;
  672 
  673         switch (cmd) {
  674         case CRIOGET:
  675                 MALLOC(fcr, struct fcrypt *,
  676                     sizeof(struct fcrypt), M_XDATA, M_WAITOK);
  677                 TAILQ_INIT(&fcr->csessions);
  678                 fcr->sesn = 0;
  679 
  680                 error = falloc(p, &f, &fd);
  681                 if (error) {
  682                         FREE(fcr, M_XDATA);
  683                         return (error);
  684                 }
  685                 f->f_flag = FREAD | FWRITE;
  686                 f->f_type = DTYPE_CRYPTO;
  687                 f->f_ops = &cryptofops;
  688                 f->f_data = fcr;
  689                 *(u_int32_t *)data = fd;
  690                 FILE_SET_MATURE(f);
  691                 break;
  692         default:
  693                 error = EINVAL;
  694                 break;
  695         }
  696         return (error);
  697 }
  698 
  699 int
  700 cryptopoll(dev_t dev, int events, struct proc *p)
  701 {
  702         return (seltrue(dev, events, p));
  703 }
  704 
  705 struct csession *
  706 csefind(struct fcrypt *fcr, u_int ses)
  707 {
  708         struct csession *cse;
  709 
  710         TAILQ_FOREACH(cse, &fcr->csessions, next)
  711                 if (cse->ses == ses)
  712                         return (cse);
  713         return (NULL);
  714 }
  715 
  716 int
  717 csedelete(struct fcrypt *fcr, struct csession *cse_del)
  718 {
  719         struct csession *cse;
  720 
  721         TAILQ_FOREACH(cse, &fcr->csessions, next) {
  722                 if (cse == cse_del) {
  723                         TAILQ_REMOVE(&fcr->csessions, cse, next);
  724                         return (1);
  725                 }
  726         }
  727         return (0);
  728 }
  729 
  730 struct csession *
  731 cseadd(struct fcrypt *fcr, struct csession *cse)
  732 {
  733         TAILQ_INSERT_TAIL(&fcr->csessions, cse, next);
  734         cse->ses = fcr->sesn++;
  735         return (cse);
  736 }
  737 
  738 struct csession *
  739 csecreate(struct fcrypt *fcr, u_int64_t sid, caddr_t key, u_int64_t keylen,
  740     caddr_t mackey, u_int64_t mackeylen, u_int32_t cipher, u_int32_t mac,
  741     struct enc_xform *txform, struct auth_hash *thash)
  742 {
  743         struct csession *cse;
  744 
  745         MALLOC(cse, struct csession *, sizeof(struct csession),
  746             M_XDATA, M_NOWAIT);
  747         if (cse == NULL)
  748                 return NULL;
  749         cse->key = key;
  750         cse->keylen = keylen/8;
  751         cse->mackey = mackey;
  752         cse->mackeylen = mackeylen/8;
  753         cse->sid = sid;
  754         cse->cipher = cipher;
  755         cse->mac = mac;
  756         cse->txform = txform;
  757         cse->thash = thash;
  758         cseadd(fcr, cse);
  759         return (cse);
  760 }
  761 
  762 int
  763 csefree(struct csession *cse)
  764 {
  765         int error;
  766 
  767         error = crypto_freesession(cse->sid);
  768         if (cse->key)
  769                 FREE(cse->key, M_XDATA);
  770         if (cse->mackey)
  771                 FREE(cse->mackey, M_XDATA);
  772         FREE(cse, M_XDATA);
  773         return (error);
  774 }

/* [<][>][^][v][top][bottom][index][help] */