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

Cache object: 3abeb53cd59f8be44775b079dc1216b3


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