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/cryptosoft.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: cryptosoft.c,v 1.35 2002/04/26 08:43:50 deraadt Exp $ */
    2 
    3 /*-
    4  * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
    5  * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
    6  *
    7  * This code was written by Angelos D. Keromytis in Athens, Greece, in
    8  * February 2000. Network Security Technologies Inc. (NSTI) kindly
    9  * supported the development of this code.
   10  *
   11  * Copyright (c) 2000, 2001 Angelos D. Keromytis
   12  *
   13  * Permission to use, copy, and modify this software with or without fee
   14  * is hereby granted, provided that this entire notice is included in
   15  * all source code copies of any software which is or includes a copy or
   16  * modification of this software.
   17  *
   18  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
   19  * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
   20  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
   21  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
   22  * PURPOSE.
   23  */
   24 
   25 #include <sys/cdefs.h>
   26 __FBSDID("$FreeBSD: releng/8.1/sys/opencrypto/cryptosoft.c 202477 2010-01-17 13:36:13Z bz $");
   27 
   28 #include <sys/param.h>
   29 #include <sys/systm.h>
   30 #include <sys/malloc.h>
   31 #include <sys/mbuf.h>
   32 #include <sys/module.h>
   33 #include <sys/sysctl.h>
   34 #include <sys/errno.h>
   35 #include <sys/random.h>
   36 #include <sys/kernel.h>
   37 #include <sys/uio.h>
   38 
   39 #include <crypto/blowfish/blowfish.h>
   40 #include <crypto/sha1.h>
   41 #include <opencrypto/rmd160.h>
   42 #include <opencrypto/cast.h>
   43 #include <opencrypto/skipjack.h>
   44 #include <sys/md5.h>
   45 
   46 #include <opencrypto/cryptodev.h>
   47 #include <opencrypto/cryptosoft.h>
   48 #include <opencrypto/xform.h>
   49 
   50 #include <sys/kobj.h>
   51 #include <sys/bus.h>
   52 #include "cryptodev_if.h"
   53 
   54 static  int32_t swcr_id;
   55 static  struct swcr_data **swcr_sessions = NULL;
   56 static  u_int32_t swcr_sesnum;
   57 
   58 u_int8_t hmac_ipad_buffer[HMAC_MAX_BLOCK_LEN];
   59 u_int8_t hmac_opad_buffer[HMAC_MAX_BLOCK_LEN];
   60 
   61 static  int swcr_encdec(struct cryptodesc *, struct swcr_data *, caddr_t, int);
   62 static  int swcr_authcompute(struct cryptodesc *, struct swcr_data *, caddr_t, int);
   63 static  int swcr_compdec(struct cryptodesc *, struct swcr_data *, caddr_t, int);
   64 static  int swcr_freesession(device_t dev, u_int64_t tid);
   65 
   66 /*
   67  * Apply a symmetric encryption/decryption algorithm.
   68  */
   69 static int
   70 swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
   71     int flags)
   72 {
   73         unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN], *idat;
   74         unsigned char *ivp, piv[EALG_MAX_BLOCK_LEN];
   75         struct enc_xform *exf;
   76         int i, k, j, blks;
   77 
   78         exf = sw->sw_exf;
   79         blks = exf->blocksize;
   80 
   81         /* Check for non-padded data */
   82         if (crd->crd_len % blks)
   83                 return EINVAL;
   84 
   85         /* Initialize the IV */
   86         if (crd->crd_flags & CRD_F_ENCRYPT) {
   87                 /* IV explicitly provided ? */
   88                 if (crd->crd_flags & CRD_F_IV_EXPLICIT)
   89                         bcopy(crd->crd_iv, iv, blks);
   90                 else
   91                         arc4rand(iv, blks, 0);
   92 
   93                 /* Do we need to write the IV */
   94                 if (!(crd->crd_flags & CRD_F_IV_PRESENT))
   95                         crypto_copyback(flags, buf, crd->crd_inject, blks, iv);
   96 
   97         } else {        /* Decryption */
   98                         /* IV explicitly provided ? */
   99                 if (crd->crd_flags & CRD_F_IV_EXPLICIT)
  100                         bcopy(crd->crd_iv, iv, blks);
  101                 else {
  102                         /* Get IV off buf */
  103                         crypto_copydata(flags, buf, crd->crd_inject, blks, iv);
  104                 }
  105         }
  106 
  107         if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {
  108                 int error; 
  109 
  110                 if (sw->sw_kschedule)
  111                         exf->zerokey(&(sw->sw_kschedule));
  112                 error = exf->setkey(&sw->sw_kschedule,
  113                                 crd->crd_key, crd->crd_klen / 8);
  114                 if (error)
  115                         return (error);
  116         }
  117         ivp = iv;
  118 
  119         if (flags & CRYPTO_F_IMBUF) {
  120                 struct mbuf *m = (struct mbuf *) buf;
  121 
  122                 /* Find beginning of data */
  123                 m = m_getptr(m, crd->crd_skip, &k);
  124                 if (m == NULL)
  125                         return EINVAL;
  126 
  127                 i = crd->crd_len;
  128 
  129                 while (i > 0) {
  130                         /*
  131                          * If there's insufficient data at the end of
  132                          * an mbuf, we have to do some copying.
  133                          */
  134                         if (m->m_len < k + blks && m->m_len != k) {
  135                                 m_copydata(m, k, blks, blk);
  136 
  137                                 /* Actual encryption/decryption */
  138                                 if (crd->crd_flags & CRD_F_ENCRYPT) {
  139                                         /* XOR with previous block */
  140                                         for (j = 0; j < blks; j++)
  141                                                 blk[j] ^= ivp[j];
  142 
  143                                         exf->encrypt(sw->sw_kschedule, blk);
  144 
  145                                         /*
  146                                          * Keep encrypted block for XOR'ing
  147                                          * with next block
  148                                          */
  149                                         bcopy(blk, iv, blks);
  150                                         ivp = iv;
  151                                 } else {        /* decrypt */
  152                                         /*      
  153                                          * Keep encrypted block for XOR'ing
  154                                          * with next block
  155                                          */
  156                                         if (ivp == iv)
  157                                                 bcopy(blk, piv, blks);
  158                                         else
  159                                                 bcopy(blk, iv, blks);
  160 
  161                                         exf->decrypt(sw->sw_kschedule, blk);
  162 
  163                                         /* XOR with previous block */
  164                                         for (j = 0; j < blks; j++)
  165                                                 blk[j] ^= ivp[j];
  166 
  167                                         if (ivp == iv)
  168                                                 bcopy(piv, iv, blks);
  169                                         else
  170                                                 ivp = iv;
  171                                 }
  172 
  173                                 /* Copy back decrypted block */
  174                                 m_copyback(m, k, blks, blk);
  175 
  176                                 /* Advance pointer */
  177                                 m = m_getptr(m, k + blks, &k);
  178                                 if (m == NULL)
  179                                         return EINVAL;
  180 
  181                                 i -= blks;
  182 
  183                                 /* Could be done... */
  184                                 if (i == 0)
  185                                         break;
  186                         }
  187 
  188                         /* Skip possibly empty mbufs */
  189                         if (k == m->m_len) {
  190                                 for (m = m->m_next; m && m->m_len == 0;
  191                                     m = m->m_next)
  192                                         ;
  193                                 k = 0;
  194                         }
  195 
  196                         /* Sanity check */
  197                         if (m == NULL)
  198                                 return EINVAL;
  199 
  200                         /*
  201                          * Warning: idat may point to garbage here, but
  202                          * we only use it in the while() loop, only if
  203                          * there are indeed enough data.
  204                          */
  205                         idat = mtod(m, unsigned char *) + k;
  206 
  207                         while (m->m_len >= k + blks && i > 0) {
  208                                 if (crd->crd_flags & CRD_F_ENCRYPT) {
  209                                         /* XOR with previous block/IV */
  210                                         for (j = 0; j < blks; j++)
  211                                                 idat[j] ^= ivp[j];
  212 
  213                                         exf->encrypt(sw->sw_kschedule, idat);
  214                                         ivp = idat;
  215                                 } else {        /* decrypt */
  216                                         /*
  217                                          * Keep encrypted block to be used
  218                                          * in next block's processing.
  219                                          */
  220                                         if (ivp == iv)
  221                                                 bcopy(idat, piv, blks);
  222                                         else
  223                                                 bcopy(idat, iv, blks);
  224 
  225                                         exf->decrypt(sw->sw_kschedule, idat);
  226 
  227                                         /* XOR with previous block/IV */
  228                                         for (j = 0; j < blks; j++)
  229                                                 idat[j] ^= ivp[j];
  230 
  231                                         if (ivp == iv)
  232                                                 bcopy(piv, iv, blks);
  233                                         else
  234                                                 ivp = iv;
  235                                 }
  236 
  237                                 idat += blks;
  238                                 k += blks;
  239                                 i -= blks;
  240                         }
  241                 }
  242 
  243                 return 0; /* Done with mbuf encryption/decryption */
  244         } else if (flags & CRYPTO_F_IOV) {
  245                 struct uio *uio = (struct uio *) buf;
  246                 struct iovec *iov;
  247 
  248                 /* Find beginning of data */
  249                 iov = cuio_getptr(uio, crd->crd_skip, &k);
  250                 if (iov == NULL)
  251                         return EINVAL;
  252 
  253                 i = crd->crd_len;
  254 
  255                 while (i > 0) {
  256                         /*
  257                          * If there's insufficient data at the end of
  258                          * an iovec, we have to do some copying.
  259                          */
  260                         if (iov->iov_len < k + blks && iov->iov_len != k) {
  261                                 cuio_copydata(uio, k, blks, blk);
  262 
  263                                 /* Actual encryption/decryption */
  264                                 if (crd->crd_flags & CRD_F_ENCRYPT) {
  265                                         /* XOR with previous block */
  266                                         for (j = 0; j < blks; j++)
  267                                                 blk[j] ^= ivp[j];
  268 
  269                                         exf->encrypt(sw->sw_kschedule, blk);
  270 
  271                                         /*
  272                                          * Keep encrypted block for XOR'ing
  273                                          * with next block
  274                                          */
  275                                         bcopy(blk, iv, blks);
  276                                         ivp = iv;
  277                                 } else {        /* decrypt */
  278                                         /*      
  279                                          * Keep encrypted block for XOR'ing
  280                                          * with next block
  281                                          */
  282                                         if (ivp == iv)
  283                                                 bcopy(blk, piv, blks);
  284                                         else
  285                                                 bcopy(blk, iv, blks);
  286 
  287                                         exf->decrypt(sw->sw_kschedule, blk);
  288 
  289                                         /* XOR with previous block */
  290                                         for (j = 0; j < blks; j++)
  291                                                 blk[j] ^= ivp[j];
  292 
  293                                         if (ivp == iv)
  294                                                 bcopy(piv, iv, blks);
  295                                         else
  296                                                 ivp = iv;
  297                                 }
  298 
  299                                 /* Copy back decrypted block */
  300                                 cuio_copyback(uio, k, blks, blk);
  301 
  302                                 /* Advance pointer */
  303                                 iov = cuio_getptr(uio, k + blks, &k);
  304                                 if (iov == NULL)
  305                                         return EINVAL;
  306 
  307                                 i -= blks;
  308 
  309                                 /* Could be done... */
  310                                 if (i == 0)
  311                                         break;
  312                         }
  313 
  314                         /*
  315                          * Warning: idat may point to garbage here, but
  316                          * we only use it in the while() loop, only if
  317                          * there are indeed enough data.
  318                          */
  319                         idat = (char *)iov->iov_base + k;
  320 
  321                         while (iov->iov_len >= k + blks && i > 0) {
  322                                 if (crd->crd_flags & CRD_F_ENCRYPT) {
  323                                         /* XOR with previous block/IV */
  324                                         for (j = 0; j < blks; j++)
  325                                                 idat[j] ^= ivp[j];
  326 
  327                                         exf->encrypt(sw->sw_kschedule, idat);
  328                                         ivp = idat;
  329                                 } else {        /* decrypt */
  330                                         /*
  331                                          * Keep encrypted block to be used
  332                                          * in next block's processing.
  333                                          */
  334                                         if (ivp == iv)
  335                                                 bcopy(idat, piv, blks);
  336                                         else
  337                                                 bcopy(idat, iv, blks);
  338 
  339                                         exf->decrypt(sw->sw_kschedule, idat);
  340 
  341                                         /* XOR with previous block/IV */
  342                                         for (j = 0; j < blks; j++)
  343                                                 idat[j] ^= ivp[j];
  344 
  345                                         if (ivp == iv)
  346                                                 bcopy(piv, iv, blks);
  347                                         else
  348                                                 ivp = iv;
  349                                 }
  350 
  351                                 idat += blks;
  352                                 k += blks;
  353                                 i -= blks;
  354                         }
  355                         if (k == iov->iov_len) {
  356                                 iov++;
  357                                 k = 0;
  358                         }
  359                 }
  360 
  361                 return 0; /* Done with iovec encryption/decryption */
  362         } else {        /* contiguous buffer */
  363                 if (crd->crd_flags & CRD_F_ENCRYPT) {
  364                         for (i = crd->crd_skip;
  365                             i < crd->crd_skip + crd->crd_len; i += blks) {
  366                                 /* XOR with the IV/previous block, as appropriate. */
  367                                 if (i == crd->crd_skip)
  368                                         for (k = 0; k < blks; k++)
  369                                                 buf[i + k] ^= ivp[k];
  370                                 else
  371                                         for (k = 0; k < blks; k++)
  372                                                 buf[i + k] ^= buf[i + k - blks];
  373                                 exf->encrypt(sw->sw_kschedule, buf + i);
  374                         }
  375                 } else {                /* Decrypt */
  376                         /*
  377                          * Start at the end, so we don't need to keep the encrypted
  378                          * block as the IV for the next block.
  379                          */
  380                         for (i = crd->crd_skip + crd->crd_len - blks;
  381                             i >= crd->crd_skip; i -= blks) {
  382                                 exf->decrypt(sw->sw_kschedule, buf + i);
  383 
  384                                 /* XOR with the IV/previous block, as appropriate */
  385                                 if (i == crd->crd_skip)
  386                                         for (k = 0; k < blks; k++)
  387                                                 buf[i + k] ^= ivp[k];
  388                                 else
  389                                         for (k = 0; k < blks; k++)
  390                                                 buf[i + k] ^= buf[i + k - blks];
  391                         }
  392                 }
  393 
  394                 return 0; /* Done with contiguous buffer encryption/decryption */
  395         }
  396 
  397         /* Unreachable */
  398         return EINVAL;
  399 }
  400 
  401 static void
  402 swcr_authprepare(struct auth_hash *axf, struct swcr_data *sw, u_char *key,
  403     int klen)
  404 {
  405         int k;
  406 
  407         klen /= 8;
  408 
  409         switch (axf->type) {
  410         case CRYPTO_MD5_HMAC:
  411         case CRYPTO_SHA1_HMAC:
  412         case CRYPTO_SHA2_256_HMAC:
  413         case CRYPTO_SHA2_384_HMAC:
  414         case CRYPTO_SHA2_512_HMAC:
  415         case CRYPTO_NULL_HMAC:
  416         case CRYPTO_RIPEMD160_HMAC:
  417                 for (k = 0; k < klen; k++)
  418                         key[k] ^= HMAC_IPAD_VAL;
  419         
  420                 axf->Init(sw->sw_ictx);
  421                 axf->Update(sw->sw_ictx, key, klen);
  422                 axf->Update(sw->sw_ictx, hmac_ipad_buffer, axf->blocksize - klen);
  423         
  424                 for (k = 0; k < klen; k++)
  425                         key[k] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
  426         
  427                 axf->Init(sw->sw_octx);
  428                 axf->Update(sw->sw_octx, key, klen);
  429                 axf->Update(sw->sw_octx, hmac_opad_buffer, axf->blocksize - klen);
  430         
  431                 for (k = 0; k < klen; k++)
  432                         key[k] ^= HMAC_OPAD_VAL;
  433                 break;
  434         case CRYPTO_MD5_KPDK:
  435         case CRYPTO_SHA1_KPDK:
  436         {
  437                 /* 
  438                  * We need a buffer that can hold an md5 and a sha1 result
  439                  * just to throw it away.
  440                  * What we do here is the initial part of:
  441                  *   ALGO( key, keyfill, .. )
  442                  * adding the key to sw_ictx and abusing Final() to get the
  443                  * "keyfill" padding.
  444                  * In addition we abuse the sw_octx to save the key to have
  445                  * it to be able to append it at the end in swcr_authcompute().
  446                  */
  447                 u_char buf[SHA1_RESULTLEN];
  448 
  449                 sw->sw_klen = klen;
  450                 bcopy(key, sw->sw_octx, klen);
  451                 axf->Init(sw->sw_ictx);
  452                 axf->Update(sw->sw_ictx, key, klen);
  453                 axf->Final(buf, sw->sw_ictx);
  454                 break;
  455         }
  456         default:
  457                 printf("%s: CRD_F_KEY_EXPLICIT flag given, but algorithm %d "
  458                     "doesn't use keys.\n", __func__, axf->type);
  459         }
  460 }
  461 
  462 /*
  463  * Compute keyed-hash authenticator.
  464  */
  465 static int
  466 swcr_authcompute(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
  467     int flags)
  468 {
  469         unsigned char aalg[HASH_MAX_LEN];
  470         struct auth_hash *axf;
  471         union authctx ctx;
  472         int err;
  473 
  474         if (sw->sw_ictx == 0)
  475                 return EINVAL;
  476 
  477         axf = sw->sw_axf;
  478 
  479         if (crd->crd_flags & CRD_F_KEY_EXPLICIT)
  480                 swcr_authprepare(axf, sw, crd->crd_key, crd->crd_klen);
  481 
  482         bcopy(sw->sw_ictx, &ctx, axf->ctxsize);
  483 
  484         err = crypto_apply(flags, buf, crd->crd_skip, crd->crd_len,
  485             (int (*)(void *, void *, unsigned int))axf->Update, (caddr_t)&ctx);
  486         if (err)
  487                 return err;
  488 
  489         switch (sw->sw_alg) {
  490         case CRYPTO_MD5_HMAC:
  491         case CRYPTO_SHA1_HMAC:
  492         case CRYPTO_SHA2_256_HMAC:
  493         case CRYPTO_SHA2_384_HMAC:
  494         case CRYPTO_SHA2_512_HMAC:
  495         case CRYPTO_RIPEMD160_HMAC:
  496                 if (sw->sw_octx == NULL)
  497                         return EINVAL;
  498 
  499                 axf->Final(aalg, &ctx);
  500                 bcopy(sw->sw_octx, &ctx, axf->ctxsize);
  501                 axf->Update(&ctx, aalg, axf->hashsize);
  502                 axf->Final(aalg, &ctx);
  503                 break;
  504 
  505         case CRYPTO_MD5_KPDK:
  506         case CRYPTO_SHA1_KPDK:
  507                 /* If we have no key saved, return error. */
  508                 if (sw->sw_octx == NULL)
  509                         return EINVAL;
  510 
  511                 /*
  512                  * Add the trailing copy of the key (see comment in
  513                  * swcr_authprepare()) after the data:
  514                  *   ALGO( .., key, algofill )
  515                  * and let Final() do the proper, natural "algofill"
  516                  * padding.
  517                  */
  518                 axf->Update(&ctx, sw->sw_octx, sw->sw_klen);
  519                 axf->Final(aalg, &ctx);
  520                 break;
  521 
  522         case CRYPTO_NULL_HMAC:
  523                 axf->Final(aalg, &ctx);
  524                 break;
  525         }
  526 
  527         /* Inject the authentication data */
  528         crypto_copyback(flags, buf, crd->crd_inject,
  529             sw->sw_mlen == 0 ? axf->hashsize : sw->sw_mlen, aalg);
  530         return 0;
  531 }
  532 
  533 /*
  534  * Apply a compression/decompression algorithm
  535  */
  536 static int
  537 swcr_compdec(struct cryptodesc *crd, struct swcr_data *sw,
  538     caddr_t buf, int flags)
  539 {
  540         u_int8_t *data, *out;
  541         struct comp_algo *cxf;
  542         int adj;
  543         u_int32_t result;
  544 
  545         cxf = sw->sw_cxf;
  546 
  547         /* We must handle the whole buffer of data in one time
  548          * then if there is not all the data in the mbuf, we must
  549          * copy in a buffer.
  550          */
  551 
  552         data = malloc(crd->crd_len, M_CRYPTO_DATA,  M_NOWAIT);
  553         if (data == NULL)
  554                 return (EINVAL);
  555         crypto_copydata(flags, buf, crd->crd_skip, crd->crd_len, data);
  556 
  557         if (crd->crd_flags & CRD_F_COMP)
  558                 result = cxf->compress(data, crd->crd_len, &out);
  559         else
  560                 result = cxf->decompress(data, crd->crd_len, &out);
  561 
  562         free(data, M_CRYPTO_DATA);
  563         if (result == 0)
  564                 return EINVAL;
  565 
  566         /* Copy back the (de)compressed data. m_copyback is
  567          * extending the mbuf as necessary.
  568          */
  569         sw->sw_size = result;
  570         /* Check the compressed size when doing compression */
  571         if (crd->crd_flags & CRD_F_COMP) {
  572                 if (result >= crd->crd_len) {
  573                         /* Compression was useless, we lost time */
  574                         free(out, M_CRYPTO_DATA);
  575                         return 0;
  576                 }
  577         }
  578 
  579         crypto_copyback(flags, buf, crd->crd_skip, result, out);
  580         if (result < crd->crd_len) {
  581                 adj = result - crd->crd_len;
  582                 if (flags & CRYPTO_F_IMBUF) {
  583                         adj = result - crd->crd_len;
  584                         m_adj((struct mbuf *)buf, adj);
  585                 } else if (flags & CRYPTO_F_IOV) {
  586                         struct uio *uio = (struct uio *)buf;
  587                         int ind;
  588 
  589                         adj = crd->crd_len - result;
  590                         ind = uio->uio_iovcnt - 1;
  591 
  592                         while (adj > 0 && ind >= 0) {
  593                                 if (adj < uio->uio_iov[ind].iov_len) {
  594                                         uio->uio_iov[ind].iov_len -= adj;
  595                                         break;
  596                                 }
  597 
  598                                 adj -= uio->uio_iov[ind].iov_len;
  599                                 uio->uio_iov[ind].iov_len = 0;
  600                                 ind--;
  601                                 uio->uio_iovcnt--;
  602                         }
  603                 }
  604         }
  605         free(out, M_CRYPTO_DATA);
  606         return 0;
  607 }
  608 
  609 /*
  610  * Generate a new software session.
  611  */
  612 static int
  613 swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
  614 {
  615         struct swcr_data **swd;
  616         struct auth_hash *axf;
  617         struct enc_xform *txf;
  618         struct comp_algo *cxf;
  619         u_int32_t i;
  620         int error;
  621 
  622         if (sid == NULL || cri == NULL)
  623                 return EINVAL;
  624 
  625         if (swcr_sessions) {
  626                 for (i = 1; i < swcr_sesnum; i++)
  627                         if (swcr_sessions[i] == NULL)
  628                                 break;
  629         } else
  630                 i = 1;          /* NB: to silence compiler warning */
  631 
  632         if (swcr_sessions == NULL || i == swcr_sesnum) {
  633                 if (swcr_sessions == NULL) {
  634                         i = 1; /* We leave swcr_sessions[0] empty */
  635                         swcr_sesnum = CRYPTO_SW_SESSIONS;
  636                 } else
  637                         swcr_sesnum *= 2;
  638 
  639                 swd = malloc(swcr_sesnum * sizeof(struct swcr_data *),
  640                     M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
  641                 if (swd == NULL) {
  642                         /* Reset session number */
  643                         if (swcr_sesnum == CRYPTO_SW_SESSIONS)
  644                                 swcr_sesnum = 0;
  645                         else
  646                                 swcr_sesnum /= 2;
  647                         return ENOBUFS;
  648                 }
  649 
  650                 /* Copy existing sessions */
  651                 if (swcr_sessions != NULL) {
  652                         bcopy(swcr_sessions, swd,
  653                             (swcr_sesnum / 2) * sizeof(struct swcr_data *));
  654                         free(swcr_sessions, M_CRYPTO_DATA);
  655                 }
  656 
  657                 swcr_sessions = swd;
  658         }
  659 
  660         swd = &swcr_sessions[i];
  661         *sid = i;
  662 
  663         while (cri) {
  664                 *swd = malloc(sizeof(struct swcr_data),
  665                     M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
  666                 if (*swd == NULL) {
  667                         swcr_freesession(dev, i);
  668                         return ENOBUFS;
  669                 }
  670 
  671                 switch (cri->cri_alg) {
  672                 case CRYPTO_DES_CBC:
  673                         txf = &enc_xform_des;
  674                         goto enccommon;
  675                 case CRYPTO_3DES_CBC:
  676                         txf = &enc_xform_3des;
  677                         goto enccommon;
  678                 case CRYPTO_BLF_CBC:
  679                         txf = &enc_xform_blf;
  680                         goto enccommon;
  681                 case CRYPTO_CAST_CBC:
  682                         txf = &enc_xform_cast5;
  683                         goto enccommon;
  684                 case CRYPTO_SKIPJACK_CBC:
  685                         txf = &enc_xform_skipjack;
  686                         goto enccommon;
  687                 case CRYPTO_RIJNDAEL128_CBC:
  688                         txf = &enc_xform_rijndael128;
  689                         goto enccommon;
  690                 case CRYPTO_CAMELLIA_CBC:
  691                         txf = &enc_xform_camellia;
  692                         goto enccommon;
  693                 case CRYPTO_NULL_CBC:
  694                         txf = &enc_xform_null;
  695                         goto enccommon;
  696                 enccommon:
  697                         if (cri->cri_key != NULL) {
  698                                 error = txf->setkey(&((*swd)->sw_kschedule),
  699                                     cri->cri_key, cri->cri_klen / 8);
  700                                 if (error) {
  701                                         swcr_freesession(dev, i);
  702                                         return error;
  703                                 }
  704                         }
  705                         (*swd)->sw_exf = txf;
  706                         break;
  707         
  708                 case CRYPTO_MD5_HMAC:
  709                         axf = &auth_hash_hmac_md5;
  710                         goto authcommon;
  711                 case CRYPTO_SHA1_HMAC:
  712                         axf = &auth_hash_hmac_sha1;
  713                         goto authcommon;
  714                 case CRYPTO_SHA2_256_HMAC:
  715                         axf = &auth_hash_hmac_sha2_256;
  716                         goto authcommon;
  717                 case CRYPTO_SHA2_384_HMAC:
  718                         axf = &auth_hash_hmac_sha2_384;
  719                         goto authcommon;
  720                 case CRYPTO_SHA2_512_HMAC:
  721                         axf = &auth_hash_hmac_sha2_512;
  722                         goto authcommon;
  723                 case CRYPTO_NULL_HMAC:
  724                         axf = &auth_hash_null;
  725                         goto authcommon;
  726                 case CRYPTO_RIPEMD160_HMAC:
  727                         axf = &auth_hash_hmac_ripemd_160;
  728                 authcommon:
  729                         (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
  730                             M_NOWAIT);
  731                         if ((*swd)->sw_ictx == NULL) {
  732                                 swcr_freesession(dev, i);
  733                                 return ENOBUFS;
  734                         }
  735         
  736                         (*swd)->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA,
  737                             M_NOWAIT);
  738                         if ((*swd)->sw_octx == NULL) {
  739                                 swcr_freesession(dev, i);
  740                                 return ENOBUFS;
  741                         }
  742 
  743                         if (cri->cri_key != NULL) {
  744                                 swcr_authprepare(axf, *swd, cri->cri_key,
  745                                     cri->cri_klen);
  746                         }
  747 
  748                         (*swd)->sw_mlen = cri->cri_mlen;
  749                         (*swd)->sw_axf = axf;
  750                         break;
  751         
  752                 case CRYPTO_MD5_KPDK:
  753                         axf = &auth_hash_key_md5;
  754                         goto auth2common;
  755         
  756                 case CRYPTO_SHA1_KPDK:
  757                         axf = &auth_hash_key_sha1;
  758                 auth2common:
  759                         (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
  760                             M_NOWAIT);
  761                         if ((*swd)->sw_ictx == NULL) {
  762                                 swcr_freesession(dev, i);
  763                                 return ENOBUFS;
  764                         }
  765         
  766                         (*swd)->sw_octx = malloc(cri->cri_klen / 8,
  767                             M_CRYPTO_DATA, M_NOWAIT);
  768                         if ((*swd)->sw_octx == NULL) {
  769                                 swcr_freesession(dev, i);
  770                                 return ENOBUFS;
  771                         }
  772 
  773                         /* Store the key so we can "append" it to the payload */
  774                         if (cri->cri_key != NULL) {
  775                                 swcr_authprepare(axf, *swd, cri->cri_key,
  776                                     cri->cri_klen);
  777                         }
  778 
  779                         (*swd)->sw_mlen = cri->cri_mlen;
  780                         (*swd)->sw_axf = axf;
  781                         break;
  782 #ifdef notdef
  783                 case CRYPTO_MD5:
  784                         axf = &auth_hash_md5;
  785                         goto auth3common;
  786 
  787                 case CRYPTO_SHA1:
  788                         axf = &auth_hash_sha1;
  789                 auth3common:
  790                         (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
  791                             M_NOWAIT);
  792                         if ((*swd)->sw_ictx == NULL) {
  793                                 swcr_freesession(dev, i);
  794                                 return ENOBUFS;
  795                         }
  796 
  797                         axf->Init((*swd)->sw_ictx);
  798                         (*swd)->sw_mlen = cri->cri_mlen;
  799                         (*swd)->sw_axf = axf;
  800                         break;
  801 #endif
  802                 case CRYPTO_DEFLATE_COMP:
  803                         cxf = &comp_algo_deflate;
  804                         (*swd)->sw_cxf = cxf;
  805                         break;
  806                 default:
  807                         swcr_freesession(dev, i);
  808                         return EINVAL;
  809                 }
  810         
  811                 (*swd)->sw_alg = cri->cri_alg;
  812                 cri = cri->cri_next;
  813                 swd = &((*swd)->sw_next);
  814         }
  815         return 0;
  816 }
  817 
  818 /*
  819  * Free a session.
  820  */
  821 static int
  822 swcr_freesession(device_t dev, u_int64_t tid)
  823 {
  824         struct swcr_data *swd;
  825         struct enc_xform *txf;
  826         struct auth_hash *axf;
  827         struct comp_algo *cxf;
  828         u_int32_t sid = CRYPTO_SESID2LID(tid);
  829 
  830         if (sid > swcr_sesnum || swcr_sessions == NULL ||
  831             swcr_sessions[sid] == NULL)
  832                 return EINVAL;
  833 
  834         /* Silently accept and return */
  835         if (sid == 0)
  836                 return 0;
  837 
  838         while ((swd = swcr_sessions[sid]) != NULL) {
  839                 swcr_sessions[sid] = swd->sw_next;
  840 
  841                 switch (swd->sw_alg) {
  842                 case CRYPTO_DES_CBC:
  843                 case CRYPTO_3DES_CBC:
  844                 case CRYPTO_BLF_CBC:
  845                 case CRYPTO_CAST_CBC:
  846                 case CRYPTO_SKIPJACK_CBC:
  847                 case CRYPTO_RIJNDAEL128_CBC:
  848                 case CRYPTO_CAMELLIA_CBC:
  849                 case CRYPTO_NULL_CBC:
  850                         txf = swd->sw_exf;
  851 
  852                         if (swd->sw_kschedule)
  853                                 txf->zerokey(&(swd->sw_kschedule));
  854                         break;
  855 
  856                 case CRYPTO_MD5_HMAC:
  857                 case CRYPTO_SHA1_HMAC:
  858                 case CRYPTO_SHA2_256_HMAC:
  859                 case CRYPTO_SHA2_384_HMAC:
  860                 case CRYPTO_SHA2_512_HMAC:
  861                 case CRYPTO_RIPEMD160_HMAC:
  862                 case CRYPTO_NULL_HMAC:
  863                         axf = swd->sw_axf;
  864 
  865                         if (swd->sw_ictx) {
  866                                 bzero(swd->sw_ictx, axf->ctxsize);
  867                                 free(swd->sw_ictx, M_CRYPTO_DATA);
  868                         }
  869                         if (swd->sw_octx) {
  870                                 bzero(swd->sw_octx, axf->ctxsize);
  871                                 free(swd->sw_octx, M_CRYPTO_DATA);
  872                         }
  873                         break;
  874 
  875                 case CRYPTO_MD5_KPDK:
  876                 case CRYPTO_SHA1_KPDK:
  877                         axf = swd->sw_axf;
  878 
  879                         if (swd->sw_ictx) {
  880                                 bzero(swd->sw_ictx, axf->ctxsize);
  881                                 free(swd->sw_ictx, M_CRYPTO_DATA);
  882                         }
  883                         if (swd->sw_octx) {
  884                                 bzero(swd->sw_octx, swd->sw_klen);
  885                                 free(swd->sw_octx, M_CRYPTO_DATA);
  886                         }
  887                         break;
  888 
  889                 case CRYPTO_MD5:
  890                 case CRYPTO_SHA1:
  891                         axf = swd->sw_axf;
  892 
  893                         if (swd->sw_ictx)
  894                                 free(swd->sw_ictx, M_CRYPTO_DATA);
  895                         break;
  896 
  897                 case CRYPTO_DEFLATE_COMP:
  898                         cxf = swd->sw_cxf;
  899                         break;
  900                 }
  901 
  902                 free(swd, M_CRYPTO_DATA);
  903         }
  904         return 0;
  905 }
  906 
  907 /*
  908  * Process a software request.
  909  */
  910 static int
  911 swcr_process(device_t dev, struct cryptop *crp, int hint)
  912 {
  913         struct cryptodesc *crd;
  914         struct swcr_data *sw;
  915         u_int32_t lid;
  916 
  917         /* Sanity check */
  918         if (crp == NULL)
  919                 return EINVAL;
  920 
  921         if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  922                 crp->crp_etype = EINVAL;
  923                 goto done;
  924         }
  925 
  926         lid = crp->crp_sid & 0xffffffff;
  927         if (lid >= swcr_sesnum || lid == 0 || swcr_sessions[lid] == NULL) {
  928                 crp->crp_etype = ENOENT;
  929                 goto done;
  930         }
  931 
  932         /* Go through crypto descriptors, processing as we go */
  933         for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  934                 /*
  935                  * Find the crypto context.
  936                  *
  937                  * XXX Note that the logic here prevents us from having
  938                  * XXX the same algorithm multiple times in a session
  939                  * XXX (or rather, we can but it won't give us the right
  940                  * XXX results). To do that, we'd need some way of differentiating
  941                  * XXX between the various instances of an algorithm (so we can
  942                  * XXX locate the correct crypto context).
  943                  */
  944                 for (sw = swcr_sessions[lid];
  945                     sw && sw->sw_alg != crd->crd_alg;
  946                     sw = sw->sw_next)
  947                         ;
  948 
  949                 /* No such context ? */
  950                 if (sw == NULL) {
  951                         crp->crp_etype = EINVAL;
  952                         goto done;
  953                 }
  954                 switch (sw->sw_alg) {
  955                 case CRYPTO_DES_CBC:
  956                 case CRYPTO_3DES_CBC:
  957                 case CRYPTO_BLF_CBC:
  958                 case CRYPTO_CAST_CBC:
  959                 case CRYPTO_SKIPJACK_CBC:
  960                 case CRYPTO_RIJNDAEL128_CBC:
  961                 case CRYPTO_CAMELLIA_CBC:
  962                         if ((crp->crp_etype = swcr_encdec(crd, sw,
  963                             crp->crp_buf, crp->crp_flags)) != 0)
  964                                 goto done;
  965                         break;
  966                 case CRYPTO_NULL_CBC:
  967                         crp->crp_etype = 0;
  968                         break;
  969                 case CRYPTO_MD5_HMAC:
  970                 case CRYPTO_SHA1_HMAC:
  971                 case CRYPTO_SHA2_256_HMAC:
  972                 case CRYPTO_SHA2_384_HMAC:
  973                 case CRYPTO_SHA2_512_HMAC:
  974                 case CRYPTO_RIPEMD160_HMAC:
  975                 case CRYPTO_NULL_HMAC:
  976                 case CRYPTO_MD5_KPDK:
  977                 case CRYPTO_SHA1_KPDK:
  978                 case CRYPTO_MD5:
  979                 case CRYPTO_SHA1:
  980                         if ((crp->crp_etype = swcr_authcompute(crd, sw,
  981                             crp->crp_buf, crp->crp_flags)) != 0)
  982                                 goto done;
  983                         break;
  984 
  985                 case CRYPTO_DEFLATE_COMP:
  986                         if ((crp->crp_etype = swcr_compdec(crd, sw, 
  987                             crp->crp_buf, crp->crp_flags)) != 0)
  988                                 goto done;
  989                         else
  990                                 crp->crp_olen = (int)sw->sw_size;
  991                         break;
  992 
  993                 default:
  994                         /* Unknown/unsupported algorithm */
  995                         crp->crp_etype = EINVAL;
  996                         goto done;
  997                 }
  998         }
  999 
 1000 done:
 1001         crypto_done(crp);
 1002         return 0;
 1003 }
 1004 
 1005 static void
 1006 swcr_identify(driver_t *drv, device_t parent)
 1007 {
 1008         /* NB: order 10 is so we get attached after h/w devices */
 1009         if (device_find_child(parent, "cryptosoft", -1) == NULL &&
 1010             BUS_ADD_CHILD(parent, 10, "cryptosoft", -1) == 0)
 1011                 panic("cryptosoft: could not attach");
 1012 }
 1013 
 1014 static int
 1015 swcr_probe(device_t dev)
 1016 {
 1017         device_set_desc(dev, "software crypto");
 1018         return (0);
 1019 }
 1020 
 1021 static int
 1022 swcr_attach(device_t dev)
 1023 {
 1024         memset(hmac_ipad_buffer, HMAC_IPAD_VAL, HMAC_MAX_BLOCK_LEN);
 1025         memset(hmac_opad_buffer, HMAC_OPAD_VAL, HMAC_MAX_BLOCK_LEN);
 1026 
 1027         swcr_id = crypto_get_driverid(dev,
 1028                         CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC);
 1029         if (swcr_id < 0) {
 1030                 device_printf(dev, "cannot initialize!");
 1031                 return ENOMEM;
 1032         }
 1033 #define REGISTER(alg) \
 1034         crypto_register(swcr_id, alg, 0,0)
 1035         REGISTER(CRYPTO_DES_CBC);
 1036         REGISTER(CRYPTO_3DES_CBC);
 1037         REGISTER(CRYPTO_BLF_CBC);
 1038         REGISTER(CRYPTO_CAST_CBC);
 1039         REGISTER(CRYPTO_SKIPJACK_CBC);
 1040         REGISTER(CRYPTO_NULL_CBC);
 1041         REGISTER(CRYPTO_MD5_HMAC);
 1042         REGISTER(CRYPTO_SHA1_HMAC);
 1043         REGISTER(CRYPTO_SHA2_256_HMAC);
 1044         REGISTER(CRYPTO_SHA2_384_HMAC);
 1045         REGISTER(CRYPTO_SHA2_512_HMAC);
 1046         REGISTER(CRYPTO_RIPEMD160_HMAC);
 1047         REGISTER(CRYPTO_NULL_HMAC);
 1048         REGISTER(CRYPTO_MD5_KPDK);
 1049         REGISTER(CRYPTO_SHA1_KPDK);
 1050         REGISTER(CRYPTO_MD5);
 1051         REGISTER(CRYPTO_SHA1);
 1052         REGISTER(CRYPTO_RIJNDAEL128_CBC);
 1053         REGISTER(CRYPTO_CAMELLIA_CBC);
 1054         REGISTER(CRYPTO_DEFLATE_COMP);
 1055 #undef REGISTER
 1056 
 1057         return 0;
 1058 }
 1059 
 1060 static int
 1061 swcr_detach(device_t dev)
 1062 {
 1063         crypto_unregister_all(swcr_id);
 1064         if (swcr_sessions != NULL)
 1065                 free(swcr_sessions, M_CRYPTO_DATA);
 1066         return 0;
 1067 }
 1068 
 1069 static device_method_t swcr_methods[] = {
 1070         DEVMETHOD(device_identify,      swcr_identify),
 1071         DEVMETHOD(device_probe,         swcr_probe),
 1072         DEVMETHOD(device_attach,        swcr_attach),
 1073         DEVMETHOD(device_detach,        swcr_detach),
 1074 
 1075         DEVMETHOD(cryptodev_newsession, swcr_newsession),
 1076         DEVMETHOD(cryptodev_freesession,swcr_freesession),
 1077         DEVMETHOD(cryptodev_process,    swcr_process),
 1078 
 1079         {0, 0},
 1080 };
 1081 
 1082 static driver_t swcr_driver = {
 1083         "cryptosoft",
 1084         swcr_methods,
 1085         0,              /* NB: no softc */
 1086 };
 1087 static devclass_t swcr_devclass;
 1088 
 1089 /*
 1090  * NB: We explicitly reference the crypto module so we
 1091  * get the necessary ordering when built as a loadable
 1092  * module.  This is required because we bundle the crypto
 1093  * module code together with the cryptosoft driver (otherwise
 1094  * normal module dependencies would handle things).
 1095  */
 1096 extern int crypto_modevent(struct module *, int, void *);
 1097 /* XXX where to attach */
 1098 DRIVER_MODULE(cryptosoft, nexus, swcr_driver, swcr_devclass, crypto_modevent,0);
 1099 MODULE_VERSION(cryptosoft, 1);
 1100 MODULE_DEPEND(cryptosoft, crypto, 1, 1, 1);

Cache object: 9320561e9d6bd606b115c796dcee38c2


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