root/crypto/cryptosoft.c

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

DEFINITIONS

This source file includes following definitions.
  1. swcr_encdec
  2. swcr_authcompute
  3. swcr_compdec
  4. swcr_newsession
  5. swcr_freesession
  6. swcr_process
  7. swcr_init

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

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