LCOV - code coverage report
Current view: top level - crypto - cryptosoft.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 503 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 8 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: cryptosoft.c,v 1.84 2018/05/31 19:40:58 fcambus 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/errno.h>
      29             : #include <dev/rndvar.h>
      30             : #include <crypto/md5.h>
      31             : #include <crypto/sha1.h>
      32             : #include <crypto/rmd160.h>
      33             : #include <crypto/cast.h>
      34             : #include <crypto/cryptodev.h>
      35             : #include <crypto/cryptosoft.h>
      36             : #include <crypto/xform.h>
      37             : 
      38             : const u_int8_t hmac_ipad_buffer[HMAC_MAX_BLOCK_LEN] = {
      39             :         0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
      40             :         0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
      41             :         0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
      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             :         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             : };
      56             : 
      57             : const u_int8_t hmac_opad_buffer[HMAC_MAX_BLOCK_LEN] = {
      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             :         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             :         0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
      69             :         0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
      70             :         0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
      71             :         0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
      72             :         0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
      73             :         0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C
      74             : };
      75             : 
      76             : 
      77             : struct swcr_data **swcr_sessions = NULL;
      78             : u_int32_t swcr_sesnum = 0;
      79             : int32_t swcr_id = -1;
      80             : 
      81             : #define COPYBACK(x, a, b, c, d) \
      82             :         do { \
      83             :                 if ((x) == CRYPTO_BUF_MBUF) \
      84             :                         m_copyback((struct mbuf *)a,b,c,d,M_NOWAIT); \
      85             :                 else \
      86             :                         cuio_copyback((struct uio *)a,b,c,d); \
      87             :         } while (0)
      88             : #define COPYDATA(x, a, b, c, d) \
      89             :         do { \
      90             :                 if ((x) == CRYPTO_BUF_MBUF) \
      91             :                         m_copydata((struct mbuf *)a,b,c,d); \
      92             :                 else \
      93             :                         cuio_copydata((struct uio *)a,b,c,d); \
      94             :         } while (0)
      95             : 
      96             : /*
      97             :  * Apply a symmetric encryption/decryption algorithm.
      98             :  */
      99             : int
     100           0 : swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
     101             :     int outtype)
     102             : {
     103           0 :         unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN], *idat;
     104           0 :         unsigned char *ivp, *nivp, iv2[EALG_MAX_BLOCK_LEN];
     105             :         struct enc_xform *exf;
     106           0 :         int i, k, j, blks, ind, count, ivlen;
     107             :         struct mbuf *m = NULL;
     108             :         struct uio *uio = NULL;
     109             : 
     110           0 :         exf = sw->sw_exf;
     111           0 :         blks = exf->blocksize;
     112           0 :         ivlen = exf->ivsize;
     113             : 
     114             :         /* Check for non-padded data */
     115           0 :         if (crd->crd_len % blks)
     116           0 :                 return EINVAL;
     117             : 
     118           0 :         if (outtype == CRYPTO_BUF_MBUF)
     119           0 :                 m = (struct mbuf *) buf;
     120             :         else
     121           0 :                 uio = (struct uio *) buf;
     122             : 
     123             :         /* Initialize the IV */
     124           0 :         if (crd->crd_flags & CRD_F_ENCRYPT) {
     125             :                 /* IV explicitly provided ? */
     126           0 :                 if (crd->crd_flags & CRD_F_IV_EXPLICIT)
     127           0 :                         bcopy(crd->crd_iv, iv, ivlen);
     128             :                 else
     129           0 :                         arc4random_buf(iv, ivlen);
     130             : 
     131             :                 /* Do we need to write the IV */
     132           0 :                 if (!(crd->crd_flags & CRD_F_IV_PRESENT))
     133           0 :                         COPYBACK(outtype, buf, crd->crd_inject, ivlen, iv);
     134             : 
     135             :         } else {        /* Decryption */
     136             :                         /* IV explicitly provided ? */
     137           0 :                 if (crd->crd_flags & CRD_F_IV_EXPLICIT)
     138           0 :                         bcopy(crd->crd_iv, iv, ivlen);
     139             :                 else {
     140             :                         /* Get IV off buf */
     141           0 :                         COPYDATA(outtype, buf, crd->crd_inject, ivlen, iv);
     142             :                 }
     143             :         }
     144             : 
     145           0 :         ivp = iv;
     146             : 
     147             :         /*
     148             :          * xforms that provide a reinit method perform all IV
     149             :          * handling themselves.
     150             :          */
     151           0 :         if (exf->reinit)
     152           0 :                 exf->reinit(sw->sw_kschedule, iv);
     153             : 
     154           0 :         if (outtype == CRYPTO_BUF_MBUF) {
     155             :                 /* Find beginning of data */
     156           0 :                 m = m_getptr(m, crd->crd_skip, &k);
     157           0 :                 if (m == NULL)
     158           0 :                         return EINVAL;
     159             : 
     160           0 :                 i = crd->crd_len;
     161             : 
     162           0 :                 while (i > 0) {
     163             :                         /*
     164             :                          * If there's insufficient data at the end of
     165             :                          * an mbuf, we have to do some copying.
     166             :                          */
     167           0 :                         if (m->m_len < k + blks && m->m_len != k) {
     168           0 :                                 m_copydata(m, k, blks, blk);
     169             : 
     170             :                                 /* Actual encryption/decryption */
     171           0 :                                 if (exf->reinit) {
     172           0 :                                         if (crd->crd_flags & CRD_F_ENCRYPT) {
     173           0 :                                                 exf->encrypt(sw->sw_kschedule,
     174             :                                                     blk);
     175           0 :                                         } else {
     176           0 :                                                 exf->decrypt(sw->sw_kschedule,
     177             :                                                     blk);
     178             :                                         }
     179           0 :                                 } else if (crd->crd_flags & CRD_F_ENCRYPT) {
     180             :                                         /* XOR with previous block */
     181           0 :                                         for (j = 0; j < blks; j++)
     182           0 :                                                 blk[j] ^= ivp[j];
     183             : 
     184           0 :                                         exf->encrypt(sw->sw_kschedule, blk);
     185             : 
     186             :                                         /*
     187             :                                          * Keep encrypted block for XOR'ing
     188             :                                          * with next block
     189             :                                          */
     190           0 :                                         bcopy(blk, iv, blks);
     191             :                                         ivp = iv;
     192           0 :                                 } else {        /* decrypt */
     193             :                                         /*
     194             :                                          * Keep encrypted block for XOR'ing
     195             :                                          * with next block
     196             :                                          */
     197           0 :                                         nivp = (ivp == iv) ? iv2 : iv;
     198           0 :                                         bcopy(blk, nivp, blks);
     199             : 
     200           0 :                                         exf->decrypt(sw->sw_kschedule, blk);
     201             : 
     202             :                                         /* XOR with previous block */
     203           0 :                                         for (j = 0; j < blks; j++)
     204           0 :                                                 blk[j] ^= ivp[j];
     205             :                                         ivp = nivp;
     206             :                                 }
     207             : 
     208             :                                 /* Copy back decrypted block */
     209           0 :                                 m_copyback(m, k, blks, blk, M_NOWAIT);
     210             : 
     211             :                                 /* Advance pointer */
     212           0 :                                 m = m_getptr(m, k + blks, &k);
     213           0 :                                 if (m == NULL)
     214           0 :                                         return EINVAL;
     215             : 
     216           0 :                                 i -= blks;
     217             : 
     218             :                                 /* Could be done... */
     219           0 :                                 if (i == 0)
     220             :                                         break;
     221             :                         }
     222             : 
     223             :                         /* Skip possibly empty mbufs */
     224           0 :                         if (k == m->m_len) {
     225           0 :                                 for (m = m->m_next; m && m->m_len == 0;
     226           0 :                                     m = m->m_next)
     227             :                                         ;
     228           0 :                                 k = 0;
     229           0 :                         }
     230             : 
     231             :                         /* Sanity check */
     232           0 :                         if (m == NULL)
     233           0 :                                 return EINVAL;
     234             : 
     235             :                         /*
     236             :                          * Warning: idat may point to garbage here, but
     237             :                          * we only use it in the while() loop, only if
     238             :                          * there are indeed enough data.
     239             :                          */
     240           0 :                         idat = mtod(m, unsigned char *) + k;
     241             : 
     242           0 :                         while (m->m_len >= k + blks && i > 0) {
     243           0 :                                 if (exf->reinit) {
     244           0 :                                         if (crd->crd_flags & CRD_F_ENCRYPT) {
     245           0 :                                                 exf->encrypt(sw->sw_kschedule,
     246             :                                                     idat);
     247           0 :                                         } else {
     248           0 :                                                 exf->decrypt(sw->sw_kschedule,
     249             :                                                     idat);
     250             :                                         }
     251           0 :                                 } else if (crd->crd_flags & CRD_F_ENCRYPT) {
     252             :                                         /* XOR with previous block/IV */
     253           0 :                                         for (j = 0; j < blks; j++)
     254           0 :                                                 idat[j] ^= ivp[j];
     255             : 
     256           0 :                                         exf->encrypt(sw->sw_kschedule, idat);
     257             :                                         ivp = idat;
     258           0 :                                 } else {        /* decrypt */
     259             :                                         /*
     260             :                                          * Keep encrypted block to be used
     261             :                                          * in next block's processing.
     262             :                                          */
     263           0 :                                         nivp = (ivp == iv) ? iv2 : iv;
     264           0 :                                         bcopy(idat, nivp, blks);
     265             : 
     266           0 :                                         exf->decrypt(sw->sw_kschedule, idat);
     267             : 
     268             :                                         /* XOR with previous block/IV */
     269           0 :                                         for (j = 0; j < blks; j++)
     270           0 :                                                 idat[j] ^= ivp[j];
     271             :                                         ivp = nivp;
     272             :                                 }
     273             : 
     274           0 :                                 idat += blks;
     275           0 :                                 k += blks;
     276           0 :                                 i -= blks;
     277             :                         }
     278             :                 }
     279             :         } else {
     280             :                 /* Find beginning of data */
     281           0 :                 count = crd->crd_skip;
     282           0 :                 ind = cuio_getptr(uio, count, &k);
     283           0 :                 if (ind == -1)
     284           0 :                         return EINVAL;
     285             : 
     286           0 :                 i = crd->crd_len;
     287             : 
     288           0 :                 while (i > 0) {
     289             :                         /*
     290             :                          * If there's insufficient data at the end,
     291             :                          * we have to do some copying.
     292             :                          */
     293           0 :                         if (uio->uio_iov[ind].iov_len < k + blks &&
     294           0 :                             uio->uio_iov[ind].iov_len != k) {
     295           0 :                                 cuio_copydata(uio, count, blks, blk);
     296             : 
     297             :                                 /* Actual encryption/decryption */
     298           0 :                                 if (exf->reinit) {
     299           0 :                                         if (crd->crd_flags & CRD_F_ENCRYPT) {
     300           0 :                                                 exf->encrypt(sw->sw_kschedule,
     301             :                                                     blk);
     302           0 :                                         } else {
     303           0 :                                                 exf->decrypt(sw->sw_kschedule,
     304             :                                                     blk);
     305             :                                         }
     306           0 :                                 } else if (crd->crd_flags & CRD_F_ENCRYPT) {
     307             :                                         /* XOR with previous block */
     308           0 :                                         for (j = 0; j < blks; j++)
     309           0 :                                                 blk[j] ^= ivp[j];
     310             : 
     311           0 :                                         exf->encrypt(sw->sw_kschedule, blk);
     312             : 
     313             :                                         /*
     314             :                                          * Keep encrypted block for XOR'ing
     315             :                                          * with next block
     316             :                                          */
     317           0 :                                         bcopy(blk, iv, blks);
     318             :                                         ivp = iv;
     319           0 :                                 } else {        /* decrypt */
     320             :                                         /*
     321             :                                          * Keep encrypted block for XOR'ing
     322             :                                          * with next block
     323             :                                          */
     324           0 :                                         nivp = (ivp == iv) ? iv2 : iv;
     325           0 :                                         bcopy(blk, nivp, blks);
     326             : 
     327           0 :                                         exf->decrypt(sw->sw_kschedule, blk);
     328             : 
     329             :                                         /* XOR with previous block */
     330           0 :                                         for (j = 0; j < blks; j++)
     331           0 :                                                 blk[j] ^= ivp[j];
     332             :                                         ivp = nivp;
     333             :                                 }
     334             : 
     335             :                                 /* Copy back decrypted block */
     336           0 :                                 cuio_copyback(uio, count, blks, blk);
     337             : 
     338           0 :                                 count += blks;
     339             : 
     340             :                                 /* Advance pointer */
     341           0 :                                 ind = cuio_getptr(uio, count, &k);
     342           0 :                                 if (ind == -1)
     343           0 :                                         return (EINVAL);
     344             : 
     345           0 :                                 i -= blks;
     346             : 
     347             :                                 /* Could be done... */
     348           0 :                                 if (i == 0)
     349             :                                         break;
     350             :                         }
     351             : 
     352             :                         /*
     353             :                          * Warning: idat may point to garbage here, but
     354             :                          * we only use it in the while() loop, only if
     355             :                          * there are indeed enough data.
     356             :                          */
     357           0 :                         idat = (char *)uio->uio_iov[ind].iov_base + k;
     358             : 
     359           0 :                         while (uio->uio_iov[ind].iov_len >= k + blks &&
     360           0 :                             i > 0) {
     361           0 :                                 if (exf->reinit) {
     362           0 :                                         if (crd->crd_flags & CRD_F_ENCRYPT) {
     363           0 :                                                 exf->encrypt(sw->sw_kschedule,
     364             :                                                     idat);
     365           0 :                                         } else {
     366           0 :                                                 exf->decrypt(sw->sw_kschedule,
     367             :                                                     idat);
     368             :                                         }
     369           0 :                                 } else if (crd->crd_flags & CRD_F_ENCRYPT) {
     370             :                                         /* XOR with previous block/IV */
     371           0 :                                         for (j = 0; j < blks; j++)
     372           0 :                                                 idat[j] ^= ivp[j];
     373             : 
     374           0 :                                         exf->encrypt(sw->sw_kschedule, idat);
     375             :                                         ivp = idat;
     376           0 :                                 } else {        /* decrypt */
     377             :                                         /*
     378             :                                          * Keep encrypted block to be used
     379             :                                          * in next block's processing.
     380             :                                          */
     381           0 :                                         nivp = (ivp == iv) ? iv2 : iv;
     382           0 :                                         bcopy(idat, nivp, blks);
     383             : 
     384           0 :                                         exf->decrypt(sw->sw_kschedule, idat);
     385             : 
     386             :                                         /* XOR with previous block/IV */
     387           0 :                                         for (j = 0; j < blks; j++)
     388           0 :                                                 idat[j] ^= ivp[j];
     389             :                                         ivp = nivp;
     390             :                                 }
     391             : 
     392           0 :                                 idat += blks;
     393           0 :                                 count += blks;
     394           0 :                                 k += blks;
     395           0 :                                 i -= blks;
     396             :                         }
     397             : 
     398             :                         /*
     399             :                          * Advance to the next iov if the end of the current iov
     400             :                          * is aligned with the end of a cipher block.
     401             :                          * Note that the code is equivalent to calling:
     402             :                          *      ind = cuio_getptr(uio, count, &k);
     403             :                          */
     404           0 :                         if (i > 0 && k == uio->uio_iov[ind].iov_len) {
     405           0 :                                 k = 0;
     406           0 :                                 ind++;
     407           0 :                                 if (ind >= uio->uio_iovcnt)
     408           0 :                                         return (EINVAL);
     409             :                         }
     410             :                 }
     411             :         }
     412             : 
     413           0 :         return 0; /* Done with encryption/decryption */
     414           0 : }
     415             : 
     416             : /*
     417             :  * Compute keyed-hash authenticator.
     418             :  */
     419             : int
     420           0 : swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
     421             :     struct swcr_data *sw, caddr_t buf, int outtype)
     422             : {
     423           0 :         unsigned char aalg[AALG_MAX_RESULT_LEN];
     424             :         struct auth_hash *axf;
     425           0 :         union authctx ctx;
     426             :         int err;
     427             : 
     428           0 :         if (sw->sw_ictx == 0)
     429           0 :                 return EINVAL;
     430             : 
     431           0 :         axf = sw->sw_axf;
     432             : 
     433           0 :         bcopy(sw->sw_ictx, &ctx, axf->ctxsize);
     434             : 
     435           0 :         if (outtype == CRYPTO_BUF_MBUF)
     436           0 :                 err = m_apply((struct mbuf *) buf, crd->crd_skip, crd->crd_len,
     437           0 :                     (int (*)(caddr_t, caddr_t, unsigned int)) axf->Update,
     438             :                     (caddr_t) &ctx);
     439             :         else
     440           0 :                 err = cuio_apply((struct uio *) buf, crd->crd_skip,
     441           0 :                     crd->crd_len,
     442           0 :                     (int (*)(caddr_t, caddr_t, unsigned int)) axf->Update,
     443             :                     (caddr_t) &ctx);
     444             : 
     445           0 :         if (err)
     446           0 :                 return err;
     447             : 
     448           0 :         if (crd->crd_flags & CRD_F_ESN)
     449           0 :                 axf->Update(&ctx, crd->crd_esn, 4);
     450             : 
     451           0 :         switch (sw->sw_alg) {
     452             :         case CRYPTO_MD5_HMAC:
     453             :         case CRYPTO_SHA1_HMAC:
     454             :         case CRYPTO_RIPEMD160_HMAC:
     455             :         case CRYPTO_SHA2_256_HMAC:
     456             :         case CRYPTO_SHA2_384_HMAC:
     457             :         case CRYPTO_SHA2_512_HMAC:
     458           0 :                 if (sw->sw_octx == NULL)
     459           0 :                         return EINVAL;
     460             : 
     461           0 :                 axf->Final(aalg, &ctx);
     462           0 :                 bcopy(sw->sw_octx, &ctx, axf->ctxsize);
     463           0 :                 axf->Update(&ctx, aalg, axf->hashsize);
     464           0 :                 axf->Final(aalg, &ctx);
     465           0 :                 break;
     466             :         }
     467             : 
     468             :         /* Inject the authentication data */
     469           0 :         if (outtype == CRYPTO_BUF_MBUF)
     470           0 :                 COPYBACK(outtype, buf, crd->crd_inject, axf->authsize, aalg);
     471             :         else
     472           0 :                 bcopy(aalg, crp->crp_mac, axf->authsize);
     473             : 
     474           0 :         return 0;
     475           0 : }
     476             : 
     477             : /*
     478             :  * Apply a combined encryption-authentication transformation
     479             :  */
     480             : int
     481           0 : swcr_authenc(struct cryptop *crp)
     482             : {
     483           0 :         uint32_t blkbuf[howmany(EALG_MAX_BLOCK_LEN, sizeof(uint32_t))];
     484           0 :         u_char *blk = (u_char *)blkbuf;
     485           0 :         u_char aalg[AALG_MAX_RESULT_LEN];
     486           0 :         u_char iv[EALG_MAX_BLOCK_LEN];
     487           0 :         union authctx ctx;
     488             :         struct cryptodesc *crd, *crda = NULL, *crde = NULL;
     489             :         struct swcr_data *sw, *swa, *swe = NULL;
     490             :         struct auth_hash *axf = NULL;
     491             :         struct enc_xform *exf = NULL;
     492           0 :         caddr_t buf = (caddr_t)crp->crp_buf;
     493             :         uint32_t *blkp;
     494             :         int aadlen, blksz, i, ivlen, outtype, len, iskip, oskip;
     495             : 
     496             :         ivlen = blksz = iskip = oskip = 0;
     497             : 
     498           0 :         for (i = 0; i < crp->crp_ndesc; i++) {
     499           0 :                 crd = &crp->crp_desc[i];
     500           0 :                 for (sw = swcr_sessions[crp->crp_sid & 0xffffffff];
     501           0 :                      sw && sw->sw_alg != crd->crd_alg;
     502           0 :                      sw = sw->sw_next)
     503             :                         ;
     504           0 :                 if (sw == NULL)
     505           0 :                         return (EINVAL);
     506             : 
     507           0 :                 switch (sw->sw_alg) {
     508             :                 case CRYPTO_AES_GCM_16:
     509             :                 case CRYPTO_AES_GMAC:
     510             :                 case CRYPTO_CHACHA20_POLY1305:
     511             :                         swe = sw;
     512             :                         crde = crd;
     513           0 :                         exf = swe->sw_exf;
     514           0 :                         ivlen = exf->ivsize;
     515           0 :                         break;
     516             :                 case CRYPTO_AES_128_GMAC:
     517             :                 case CRYPTO_AES_192_GMAC:
     518             :                 case CRYPTO_AES_256_GMAC:
     519             :                 case CRYPTO_CHACHA20_POLY1305_MAC:
     520             :                         swa = sw;
     521             :                         crda = crd;
     522           0 :                         axf = swa->sw_axf;
     523           0 :                         if (swa->sw_ictx == 0)
     524           0 :                                 return (EINVAL);
     525           0 :                         bcopy(swa->sw_ictx, &ctx, axf->ctxsize);
     526           0 :                         blksz = axf->blocksize;
     527           0 :                         break;
     528             :                 default:
     529           0 :                         return (EINVAL);
     530             :                 }
     531             :         }
     532           0 :         if (crde == NULL || crda == NULL)
     533           0 :                 return (EINVAL);
     534             : 
     535           0 :         if (crp->crp_flags & CRYPTO_F_IMBUF) {
     536             :                 outtype = CRYPTO_BUF_MBUF;
     537           0 :         } else {
     538             :                 outtype = CRYPTO_BUF_IOV;
     539             :         }
     540             : 
     541             :         /* Initialize the IV */
     542           0 :         if (crde->crd_flags & CRD_F_ENCRYPT) {
     543             :                 /* IV explicitly provided ? */
     544           0 :                 if (crde->crd_flags & CRD_F_IV_EXPLICIT)
     545           0 :                         bcopy(crde->crd_iv, iv, ivlen);
     546             :                 else
     547           0 :                         arc4random_buf(iv, ivlen);
     548             : 
     549             :                 /* Do we need to write the IV */
     550           0 :                 if (!(crde->crd_flags & CRD_F_IV_PRESENT))
     551           0 :                         COPYBACK(outtype, buf, crde->crd_inject, ivlen, iv);
     552             : 
     553             :         } else {        /* Decryption */
     554             :                         /* IV explicitly provided ? */
     555           0 :                 if (crde->crd_flags & CRD_F_IV_EXPLICIT)
     556           0 :                         bcopy(crde->crd_iv, iv, ivlen);
     557             :                 else {
     558             :                         /* Get IV off buf */
     559           0 :                         COPYDATA(outtype, buf, crde->crd_inject, ivlen, iv);
     560             :                 }
     561             :         }
     562             : 
     563             :         /* Supply MAC with IV */
     564           0 :         if (axf->Reinit)
     565           0 :                 axf->Reinit(&ctx, iv, ivlen);
     566             : 
     567             :         /* Supply MAC with AAD */
     568           0 :         aadlen = crda->crd_len;
     569             :         /*
     570             :          * Section 5 of RFC 4106 specifies that AAD construction consists of
     571             :          * {SPI, ESN, SN} whereas the real packet contains only {SPI, SN}.
     572             :          * Unfortunately it doesn't follow a good example set in the Section
     573             :          * 3.3.2.1 of RFC 4303 where upper part of the ESN, located in the
     574             :          * external (to the packet) memory buffer, is processed by the hash
     575             :          * function in the end thus allowing to retain simple programming
     576             :          * interfaces and avoid kludges like the one below.
     577             :          */
     578           0 :         if (crda->crd_flags & CRD_F_ESN) {
     579           0 :                 aadlen += 4;
     580             :                 /* SPI */
     581           0 :                 COPYDATA(outtype, buf, crda->crd_skip, 4, blk);
     582             :                 iskip = 4; /* loop below will start with an offset of 4 */
     583             :                 /* ESN */
     584           0 :                 bcopy(crda->crd_esn, blk + 4, 4);
     585             :                 oskip = iskip + 4; /* offset output buffer blk by 8 */
     586           0 :         }
     587           0 :         for (i = iskip; i < crda->crd_len; i += axf->hashsize) {
     588           0 :                 len = MIN(crda->crd_len - i, axf->hashsize - oskip);
     589           0 :                 COPYDATA(outtype, buf, crda->crd_skip + i, len, blk + oskip);
     590           0 :                 bzero(blk + len + oskip, axf->hashsize - len - oskip);
     591           0 :                 axf->Update(&ctx, blk, axf->hashsize);
     592             :                 oskip = 0; /* reset initial output offset */
     593             :         }
     594             : 
     595           0 :         if (exf->reinit)
     596           0 :                 exf->reinit(swe->sw_kschedule, iv);
     597             : 
     598             :         /* Do encryption/decryption with MAC */
     599           0 :         for (i = 0; i < crde->crd_len; i += blksz) {
     600           0 :                 len = MIN(crde->crd_len - i, blksz);
     601           0 :                 if (len < blksz)
     602           0 :                         bzero(blk, blksz);
     603           0 :                 COPYDATA(outtype, buf, crde->crd_skip + i, len, blk);
     604           0 :                 if (crde->crd_flags & CRD_F_ENCRYPT) {
     605           0 :                         exf->encrypt(swe->sw_kschedule, blk);
     606           0 :                         axf->Update(&ctx, blk, len);
     607           0 :                 } else {
     608           0 :                         axf->Update(&ctx, blk, len);
     609           0 :                         exf->decrypt(swe->sw_kschedule, blk);
     610             :                 }
     611           0 :                 COPYBACK(outtype, buf, crde->crd_skip + i, len, blk);
     612             :         }
     613             : 
     614             :         /* Do any required special finalization */
     615           0 :         switch (crda->crd_alg) {
     616             :                 case CRYPTO_AES_128_GMAC:
     617             :                 case CRYPTO_AES_192_GMAC:
     618             :                 case CRYPTO_AES_256_GMAC:
     619             :                         /* length block */
     620           0 :                         bzero(blk, axf->hashsize);
     621           0 :                         blkp = (uint32_t *)blk + 1;
     622           0 :                         *blkp = htobe32(aadlen * 8);
     623           0 :                         blkp = (uint32_t *)blk + 3;
     624           0 :                         *blkp = htobe32(crde->crd_len * 8);
     625           0 :                         axf->Update(&ctx, blk, axf->hashsize);
     626           0 :                         break;
     627             :                 case CRYPTO_CHACHA20_POLY1305_MAC:
     628             :                         /* length block */
     629           0 :                         bzero(blk, axf->hashsize);
     630             :                         blkp = (uint32_t *)blk;
     631           0 :                         *blkp = htole32(aadlen);
     632           0 :                         blkp = (uint32_t *)blk + 2;
     633           0 :                         *blkp = htole32(crde->crd_len);
     634           0 :                         axf->Update(&ctx, blk, axf->hashsize);
     635           0 :                         break;
     636             :         }
     637             : 
     638             :         /* Finalize MAC */
     639           0 :         axf->Final(aalg, &ctx);
     640             : 
     641             :         /* Inject the authentication data */
     642           0 :         if (outtype == CRYPTO_BUF_MBUF)
     643           0 :                 COPYBACK(outtype, buf, crda->crd_inject, axf->authsize, aalg);
     644             :         else
     645           0 :                 bcopy(aalg, crp->crp_mac, axf->authsize);
     646             : 
     647           0 :         return (0);
     648           0 : }
     649             : 
     650             : /*
     651             :  * Apply a compression/decompression algorithm
     652             :  */
     653             : int
     654           0 : swcr_compdec(struct cryptodesc *crd, struct swcr_data *sw,
     655             :     caddr_t buf, int outtype)
     656             : {
     657           0 :         u_int8_t *data, *out;
     658             :         struct comp_algo *cxf;
     659             :         int adj;
     660             :         u_int32_t result;
     661             : 
     662           0 :         cxf = sw->sw_cxf;
     663             : 
     664             :         /* We must handle the whole buffer of data in one time
     665             :          * then if there is not all the data in the mbuf, we must
     666             :          * copy in a buffer.
     667             :          */
     668             : 
     669           0 :         data = malloc(crd->crd_len, M_CRYPTO_DATA, M_NOWAIT);
     670           0 :         if (data == NULL)
     671           0 :                 return (EINVAL);
     672           0 :         COPYDATA(outtype, buf, crd->crd_skip, crd->crd_len, data);
     673             : 
     674           0 :         if (crd->crd_flags & CRD_F_COMP)
     675           0 :                 result = cxf->compress(data, crd->crd_len, &out);
     676             :         else
     677           0 :                 result = cxf->decompress(data, crd->crd_len, &out);
     678             : 
     679           0 :         free(data, M_CRYPTO_DATA, crd->crd_len);
     680           0 :         if (result == 0)
     681           0 :                 return EINVAL;
     682             : 
     683             :         /* Copy back the (de)compressed data. m_copyback is
     684             :          * extending the mbuf as necessary.
     685             :          */
     686           0 :         sw->sw_size = result;
     687             :         /* Check the compressed size when doing compression */
     688           0 :         if (crd->crd_flags & CRD_F_COMP) {
     689           0 :                 if (result > crd->crd_len) {
     690             :                         /* Compression was useless, we lost time */
     691           0 :                         free(out, M_CRYPTO_DATA, 0);
     692           0 :                         return 0;
     693             :                 }
     694             :         }
     695             : 
     696           0 :         COPYBACK(outtype, buf, crd->crd_skip, result, out);
     697           0 :         if (result < crd->crd_len) {
     698             :                 adj = result - crd->crd_len;
     699           0 :                 if (outtype == CRYPTO_BUF_MBUF) {
     700           0 :                         adj = result - crd->crd_len;
     701           0 :                         m_adj((struct mbuf *)buf, adj);
     702           0 :                 } else {
     703           0 :                         struct uio *uio = (struct uio *)buf;
     704             :                         int ind;
     705             : 
     706           0 :                         adj = crd->crd_len - result;
     707           0 :                         ind = uio->uio_iovcnt - 1;
     708             : 
     709           0 :                         while (adj > 0 && ind >= 0) {
     710           0 :                                 if (adj < uio->uio_iov[ind].iov_len) {
     711           0 :                                         uio->uio_iov[ind].iov_len -= adj;
     712           0 :                                         break;
     713             :                                 }
     714             : 
     715           0 :                                 adj -= uio->uio_iov[ind].iov_len;
     716           0 :                                 uio->uio_iov[ind].iov_len = 0;
     717           0 :                                 ind--;
     718           0 :                                 uio->uio_iovcnt--;
     719             :                         }
     720             :                 }
     721             :         }
     722           0 :         free(out, M_CRYPTO_DATA, 0);
     723           0 :         return 0;
     724           0 : }
     725             : 
     726             : /*
     727             :  * Generate a new software session.
     728             :  */
     729             : int
     730           0 : swcr_newsession(u_int32_t *sid, struct cryptoini *cri)
     731             : {
     732             :         struct swcr_data **swd;
     733             :         struct auth_hash *axf;
     734             :         struct enc_xform *txf;
     735             :         struct comp_algo *cxf;
     736             :         u_int32_t i;
     737             :         int k;
     738             : 
     739           0 :         if (sid == NULL || cri == NULL)
     740           0 :                 return EINVAL;
     741             : 
     742           0 :         if (swcr_sessions) {
     743           0 :                 for (i = 1; i < swcr_sesnum; i++)
     744           0 :                         if (swcr_sessions[i] == NULL)
     745             :                                 break;
     746             :         }
     747             : 
     748           0 :         if (swcr_sessions == NULL || i == swcr_sesnum) {
     749           0 :                 if (swcr_sessions == NULL) {
     750             :                         i = 1; /* We leave swcr_sessions[0] empty */
     751           0 :                         swcr_sesnum = CRYPTO_SW_SESSIONS;
     752           0 :                 } else
     753           0 :                         swcr_sesnum *= 2;
     754             : 
     755           0 :                 swd = mallocarray(swcr_sesnum, sizeof(struct swcr_data *),
     756             :                     M_CRYPTO_DATA, M_NOWAIT | M_ZERO);
     757           0 :                 if (swd == NULL) {
     758             :                         /* Reset session number */
     759           0 :                         if (swcr_sesnum == CRYPTO_SW_SESSIONS)
     760           0 :                                 swcr_sesnum = 0;
     761             :                         else
     762           0 :                                 swcr_sesnum /= 2;
     763           0 :                         return ENOBUFS;
     764             :                 }
     765             : 
     766             :                 /* Copy existing sessions */
     767           0 :                 if (swcr_sessions) {
     768           0 :                         bcopy(swcr_sessions, swd,
     769           0 :                             (swcr_sesnum / 2) * sizeof(struct swcr_data *));
     770           0 :                         free(swcr_sessions, M_CRYPTO_DATA,
     771           0 :                             (swcr_sesnum / 2) * sizeof(struct swcr_data *));
     772           0 :                 }
     773             : 
     774           0 :                 swcr_sessions = swd;
     775           0 :         }
     776             : 
     777           0 :         swd = &swcr_sessions[i];
     778           0 :         *sid = i;
     779             : 
     780           0 :         while (cri) {
     781           0 :                 *swd = malloc(sizeof(struct swcr_data), M_CRYPTO_DATA,
     782             :                     M_NOWAIT | M_ZERO);
     783           0 :                 if (*swd == NULL) {
     784           0 :                         swcr_freesession(i);
     785           0 :                         return ENOBUFS;
     786             :                 }
     787             : 
     788           0 :                 switch (cri->cri_alg) {
     789             :                 case CRYPTO_3DES_CBC:
     790             :                         txf = &enc_xform_3des;
     791           0 :                         goto enccommon;
     792             :                 case CRYPTO_BLF_CBC:
     793             :                         txf = &enc_xform_blf;
     794           0 :                         goto enccommon;
     795             :                 case CRYPTO_CAST_CBC:
     796             :                         txf = &enc_xform_cast5;
     797           0 :                         goto enccommon;
     798             :                 case CRYPTO_AES_CBC:
     799             :                         txf = &enc_xform_aes;
     800           0 :                         goto enccommon;
     801             :                 case CRYPTO_AES_CTR:
     802             :                         txf = &enc_xform_aes_ctr;
     803           0 :                         goto enccommon;
     804             :                 case CRYPTO_AES_XTS:
     805             :                         txf = &enc_xform_aes_xts;
     806           0 :                         goto enccommon;
     807             :                 case CRYPTO_AES_GCM_16:
     808             :                         txf = &enc_xform_aes_gcm;
     809           0 :                         goto enccommon;
     810             :                 case CRYPTO_AES_GMAC:
     811             :                         txf = &enc_xform_aes_gmac;
     812           0 :                         (*swd)->sw_exf = txf;
     813           0 :                         break;
     814             :                 case CRYPTO_CHACHA20_POLY1305:
     815             :                         txf = &enc_xform_chacha20_poly1305;
     816           0 :                         goto enccommon;
     817             :                 case CRYPTO_NULL:
     818             :                         txf = &enc_xform_null;
     819           0 :                         goto enccommon;
     820             :                 enccommon:
     821           0 :                         if (txf->ctxsize > 0) {
     822           0 :                                 (*swd)->sw_kschedule = malloc(txf->ctxsize,
     823             :                                     M_CRYPTO_DATA, M_NOWAIT | M_ZERO);
     824           0 :                                 if ((*swd)->sw_kschedule == NULL) {
     825           0 :                                         swcr_freesession(i);
     826           0 :                                         return EINVAL;
     827             :                                 }
     828             :                         }
     829           0 :                         if (txf->setkey((*swd)->sw_kschedule, cri->cri_key,
     830           0 :                             cri->cri_klen / 8) < 0) {
     831           0 :                                 swcr_freesession(i);
     832           0 :                                 return EINVAL;
     833             :                         }
     834           0 :                         (*swd)->sw_exf = txf;
     835           0 :                         break;
     836             : 
     837             :                 case CRYPTO_MD5_HMAC:
     838             :                         axf = &auth_hash_hmac_md5_96;
     839           0 :                         goto authcommon;
     840             :                 case CRYPTO_SHA1_HMAC:
     841             :                         axf = &auth_hash_hmac_sha1_96;
     842           0 :                         goto authcommon;
     843             :                 case CRYPTO_RIPEMD160_HMAC:
     844             :                         axf = &auth_hash_hmac_ripemd_160_96;
     845           0 :                         goto authcommon;
     846             :                 case CRYPTO_SHA2_256_HMAC:
     847             :                         axf = &auth_hash_hmac_sha2_256_128;
     848           0 :                         goto authcommon;
     849             :                 case CRYPTO_SHA2_384_HMAC:
     850             :                         axf = &auth_hash_hmac_sha2_384_192;
     851           0 :                         goto authcommon;
     852             :                 case CRYPTO_SHA2_512_HMAC:
     853             :                         axf = &auth_hash_hmac_sha2_512_256;
     854           0 :                         goto authcommon;
     855             :                 authcommon:
     856           0 :                         (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
     857             :                             M_NOWAIT);
     858           0 :                         if ((*swd)->sw_ictx == NULL) {
     859           0 :                                 swcr_freesession(i);
     860           0 :                                 return ENOBUFS;
     861             :                         }
     862             : 
     863           0 :                         (*swd)->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA,
     864             :                             M_NOWAIT);
     865           0 :                         if ((*swd)->sw_octx == NULL) {
     866           0 :                                 swcr_freesession(i);
     867           0 :                                 return ENOBUFS;
     868             :                         }
     869             : 
     870           0 :                         for (k = 0; k < cri->cri_klen / 8; k++)
     871           0 :                                 cri->cri_key[k] ^= HMAC_IPAD_VAL;
     872             : 
     873           0 :                         axf->Init((*swd)->sw_ictx);
     874           0 :                         axf->Update((*swd)->sw_ictx, cri->cri_key,
     875           0 :                             cri->cri_klen / 8);
     876           0 :                         axf->Update((*swd)->sw_ictx, hmac_ipad_buffer,
     877           0 :                             axf->blocksize - (cri->cri_klen / 8));
     878             : 
     879           0 :                         for (k = 0; k < cri->cri_klen / 8; k++)
     880           0 :                                 cri->cri_key[k] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
     881             : 
     882           0 :                         axf->Init((*swd)->sw_octx);
     883           0 :                         axf->Update((*swd)->sw_octx, cri->cri_key,
     884           0 :                             cri->cri_klen / 8);
     885           0 :                         axf->Update((*swd)->sw_octx, hmac_opad_buffer,
     886           0 :                             axf->blocksize - (cri->cri_klen / 8));
     887             : 
     888           0 :                         for (k = 0; k < cri->cri_klen / 8; k++)
     889           0 :                                 cri->cri_key[k] ^= HMAC_OPAD_VAL;
     890           0 :                         (*swd)->sw_axf = axf;
     891           0 :                         break;
     892             : 
     893             :                 case CRYPTO_AES_128_GMAC:
     894             :                         axf = &auth_hash_gmac_aes_128;
     895           0 :                         goto authenccommon;
     896             :                 case CRYPTO_AES_192_GMAC:
     897             :                         axf = &auth_hash_gmac_aes_192;
     898           0 :                         goto authenccommon;
     899             :                 case CRYPTO_AES_256_GMAC:
     900             :                         axf = &auth_hash_gmac_aes_256;
     901           0 :                         goto authenccommon;
     902             :                 case CRYPTO_CHACHA20_POLY1305_MAC:
     903             :                         axf = &auth_hash_chacha20_poly1305;
     904           0 :                         goto authenccommon;
     905             :                 authenccommon:
     906           0 :                         (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
     907             :                             M_NOWAIT);
     908           0 :                         if ((*swd)->sw_ictx == NULL) {
     909           0 :                                 swcr_freesession(i);
     910           0 :                                 return ENOBUFS;
     911             :                         }
     912           0 :                         axf->Init((*swd)->sw_ictx);
     913           0 :                         axf->Setkey((*swd)->sw_ictx, cri->cri_key,
     914           0 :                             cri->cri_klen / 8);
     915           0 :                         (*swd)->sw_axf = axf;
     916           0 :                         break;
     917             : 
     918             :                 case CRYPTO_DEFLATE_COMP:
     919             :                         cxf = &comp_algo_deflate;
     920           0 :                         (*swd)->sw_cxf = cxf;
     921           0 :                         break;
     922             :                 case CRYPTO_ESN:
     923             :                         /* nothing to do */
     924             :                         break;
     925             :                 default:
     926           0 :                         swcr_freesession(i);
     927           0 :                         return EINVAL;
     928             :                 }
     929             : 
     930           0 :                 (*swd)->sw_alg = cri->cri_alg;
     931           0 :                 cri = cri->cri_next;
     932           0 :                 swd = &((*swd)->sw_next);
     933             :         }
     934           0 :         return 0;
     935           0 : }
     936             : 
     937             : /*
     938             :  * Free a session.
     939             :  */
     940             : int
     941           0 : swcr_freesession(u_int64_t tid)
     942             : {
     943             :         struct swcr_data *swd;
     944             :         struct enc_xform *txf;
     945             :         struct auth_hash *axf;
     946           0 :         u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
     947             : 
     948           0 :         if (sid > swcr_sesnum || swcr_sessions == NULL ||
     949           0 :             swcr_sessions[sid] == NULL)
     950           0 :                 return EINVAL;
     951             : 
     952             :         /* Silently accept and return */
     953           0 :         if (sid == 0)
     954           0 :                 return 0;
     955             : 
     956           0 :         while ((swd = swcr_sessions[sid]) != NULL) {
     957           0 :                 swcr_sessions[sid] = swd->sw_next;
     958             : 
     959           0 :                 switch (swd->sw_alg) {
     960             :                 case CRYPTO_3DES_CBC:
     961             :                 case CRYPTO_BLF_CBC:
     962             :                 case CRYPTO_CAST_CBC:
     963             :                 case CRYPTO_AES_CBC:
     964             :                 case CRYPTO_AES_CTR:
     965             :                 case CRYPTO_AES_XTS:
     966             :                 case CRYPTO_AES_GCM_16:
     967             :                 case CRYPTO_AES_GMAC:
     968             :                 case CRYPTO_CHACHA20_POLY1305:
     969             :                 case CRYPTO_NULL:
     970           0 :                         txf = swd->sw_exf;
     971             : 
     972           0 :                         if (swd->sw_kschedule) {
     973           0 :                                 explicit_bzero(swd->sw_kschedule, txf->ctxsize);
     974           0 :                                 free(swd->sw_kschedule, M_CRYPTO_DATA,
     975           0 :                                     txf->ctxsize);
     976           0 :                         }
     977             :                         break;
     978             : 
     979             :                 case CRYPTO_MD5_HMAC:
     980             :                 case CRYPTO_SHA1_HMAC:
     981             :                 case CRYPTO_RIPEMD160_HMAC:
     982             :                 case CRYPTO_SHA2_256_HMAC:
     983             :                 case CRYPTO_SHA2_384_HMAC:
     984             :                 case CRYPTO_SHA2_512_HMAC:
     985           0 :                         axf = swd->sw_axf;
     986             : 
     987           0 :                         if (swd->sw_ictx) {
     988           0 :                                 explicit_bzero(swd->sw_ictx, axf->ctxsize);
     989           0 :                                 free(swd->sw_ictx, M_CRYPTO_DATA, axf->ctxsize);
     990           0 :                         }
     991           0 :                         if (swd->sw_octx) {
     992           0 :                                 explicit_bzero(swd->sw_octx, axf->ctxsize);
     993           0 :                                 free(swd->sw_octx, M_CRYPTO_DATA, axf->ctxsize);
     994           0 :                         }
     995             :                         break;
     996             : 
     997             :                 case CRYPTO_AES_128_GMAC:
     998             :                 case CRYPTO_AES_192_GMAC:
     999             :                 case CRYPTO_AES_256_GMAC:
    1000             :                 case CRYPTO_CHACHA20_POLY1305_MAC:
    1001           0 :                         axf = swd->sw_axf;
    1002             : 
    1003           0 :                         if (swd->sw_ictx) {
    1004           0 :                                 explicit_bzero(swd->sw_ictx, axf->ctxsize);
    1005           0 :                                 free(swd->sw_ictx, M_CRYPTO_DATA, axf->ctxsize);
    1006           0 :                         }
    1007             :                         break;
    1008             :                 }
    1009             : 
    1010           0 :                 free(swd, M_CRYPTO_DATA, sizeof(*swd));
    1011             :         }
    1012           0 :         return 0;
    1013           0 : }
    1014             : 
    1015             : /*
    1016             :  * Process a software request.
    1017             :  */
    1018             : int
    1019           0 : swcr_process(struct cryptop *crp)
    1020             : {
    1021             :         struct cryptodesc *crd;
    1022             :         struct swcr_data *sw;
    1023             :         u_int32_t lid;
    1024             :         int type;
    1025             :         int i;
    1026             : 
    1027             :         /* Sanity check */
    1028           0 :         if (crp == NULL)
    1029           0 :                 return EINVAL;
    1030             : 
    1031           0 :         if (crp->crp_ndesc < 1 || crp->crp_buf == NULL) {
    1032           0 :                 crp->crp_etype = EINVAL;
    1033           0 :                 goto done;
    1034             :         }
    1035             : 
    1036           0 :         lid = crp->crp_sid & 0xffffffff;
    1037           0 :         if (lid >= swcr_sesnum || lid == 0 || swcr_sessions[lid] == NULL) {
    1038           0 :                 crp->crp_etype = ENOENT;
    1039           0 :                 goto done;
    1040             :         }
    1041             : 
    1042           0 :         if (crp->crp_flags & CRYPTO_F_IMBUF)
    1043           0 :                 type = CRYPTO_BUF_MBUF;
    1044             :         else
    1045             :                 type = CRYPTO_BUF_IOV;
    1046             : 
    1047             :         /* Go through crypto descriptors, processing as we go */
    1048           0 :         for (i = 0; i < crp->crp_ndesc; i++) {
    1049           0 :                 crd = &crp->crp_desc[i];
    1050             :                 /*
    1051             :                  * Find the crypto context.
    1052             :                  *
    1053             :                  * XXX Note that the logic here prevents us from having
    1054             :                  * XXX the same algorithm multiple times in a session
    1055             :                  * XXX (or rather, we can but it won't give us the right
    1056             :                  * XXX results). To do that, we'd need some way of differentiating
    1057             :                  * XXX between the various instances of an algorithm (so we can
    1058             :                  * XXX locate the correct crypto context).
    1059             :                  */
    1060           0 :                 for (sw = swcr_sessions[lid];
    1061           0 :                     sw && sw->sw_alg != crd->crd_alg;
    1062           0 :                     sw = sw->sw_next)
    1063             :                         ;
    1064             : 
    1065             :                 /* No such context ? */
    1066           0 :                 if (sw == NULL) {
    1067           0 :                         crp->crp_etype = EINVAL;
    1068           0 :                         goto done;
    1069             :                 }
    1070             : 
    1071           0 :                 switch (sw->sw_alg) {
    1072             :                 case CRYPTO_NULL:
    1073             :                         break;
    1074             :                 case CRYPTO_3DES_CBC:
    1075             :                 case CRYPTO_BLF_CBC:
    1076             :                 case CRYPTO_CAST_CBC:
    1077             :                 case CRYPTO_RIJNDAEL128_CBC:
    1078             :                 case CRYPTO_AES_CTR:
    1079             :                 case CRYPTO_AES_XTS:
    1080           0 :                         if ((crp->crp_etype = swcr_encdec(crd, sw,
    1081           0 :                             crp->crp_buf, type)) != 0)
    1082             :                                 goto done;
    1083             :                         break;
    1084             :                 case CRYPTO_MD5_HMAC:
    1085             :                 case CRYPTO_SHA1_HMAC:
    1086             :                 case CRYPTO_RIPEMD160_HMAC:
    1087             :                 case CRYPTO_SHA2_256_HMAC:
    1088             :                 case CRYPTO_SHA2_384_HMAC:
    1089             :                 case CRYPTO_SHA2_512_HMAC:
    1090           0 :                         if ((crp->crp_etype = swcr_authcompute(crp, crd, sw,
    1091           0 :                             crp->crp_buf, type)) != 0)
    1092             :                                 goto done;
    1093             :                         break;
    1094             : 
    1095             :                 case CRYPTO_AES_GCM_16:
    1096             :                 case CRYPTO_AES_GMAC:
    1097             :                 case CRYPTO_AES_128_GMAC:
    1098             :                 case CRYPTO_AES_192_GMAC:
    1099             :                 case CRYPTO_AES_256_GMAC:
    1100             :                 case CRYPTO_CHACHA20_POLY1305:
    1101             :                 case CRYPTO_CHACHA20_POLY1305_MAC:
    1102           0 :                         crp->crp_etype = swcr_authenc(crp);
    1103           0 :                         goto done;
    1104             : 
    1105             :                 case CRYPTO_DEFLATE_COMP:
    1106           0 :                         if ((crp->crp_etype = swcr_compdec(crd, sw,
    1107           0 :                             crp->crp_buf, type)) != 0)
    1108             :                                 goto done;
    1109             :                         else
    1110           0 :                                 crp->crp_olen = (int)sw->sw_size;
    1111           0 :                         break;
    1112             : 
    1113             :                 default:
    1114             :                         /* Unknown/unsupported algorithm */
    1115           0 :                         crp->crp_etype = EINVAL;
    1116           0 :                         goto done;
    1117             :                 }
    1118             :         }
    1119             : 
    1120             : done:
    1121           0 :         crypto_done(crp);
    1122           0 :         return 0;
    1123           0 : }
    1124             : 
    1125             : /*
    1126             :  * Initialize the driver, called from the kernel main().
    1127             :  */
    1128             : void
    1129           0 : swcr_init(void)
    1130             : {
    1131           0 :         int algs[CRYPTO_ALGORITHM_MAX + 1];
    1132             :         int flags = CRYPTOCAP_F_SOFTWARE;
    1133             : 
    1134           0 :         swcr_id = crypto_get_driverid(flags);
    1135           0 :         if (swcr_id < 0) {
    1136             :                 /* This should never happen */
    1137           0 :                 panic("Software crypto device cannot initialize!");
    1138             :         }
    1139             : 
    1140           0 :         bzero(algs, sizeof(algs));
    1141             : 
    1142           0 :         algs[CRYPTO_3DES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
    1143           0 :         algs[CRYPTO_BLF_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
    1144           0 :         algs[CRYPTO_CAST_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
    1145           0 :         algs[CRYPTO_MD5_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
    1146           0 :         algs[CRYPTO_SHA1_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
    1147           0 :         algs[CRYPTO_RIPEMD160_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
    1148           0 :         algs[CRYPTO_AES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
    1149           0 :         algs[CRYPTO_AES_CTR] = CRYPTO_ALG_FLAG_SUPPORTED;
    1150           0 :         algs[CRYPTO_AES_XTS] = CRYPTO_ALG_FLAG_SUPPORTED;
    1151           0 :         algs[CRYPTO_AES_GCM_16] = CRYPTO_ALG_FLAG_SUPPORTED;
    1152           0 :         algs[CRYPTO_AES_GMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
    1153           0 :         algs[CRYPTO_DEFLATE_COMP] = CRYPTO_ALG_FLAG_SUPPORTED;
    1154           0 :         algs[CRYPTO_NULL] = CRYPTO_ALG_FLAG_SUPPORTED;
    1155           0 :         algs[CRYPTO_SHA2_256_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
    1156           0 :         algs[CRYPTO_SHA2_384_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
    1157           0 :         algs[CRYPTO_SHA2_512_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
    1158           0 :         algs[CRYPTO_AES_128_GMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
    1159           0 :         algs[CRYPTO_AES_192_GMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
    1160           0 :         algs[CRYPTO_AES_256_GMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
    1161           0 :         algs[CRYPTO_CHACHA20_POLY1305] = CRYPTO_ALG_FLAG_SUPPORTED;
    1162           0 :         algs[CRYPTO_CHACHA20_POLY1305_MAC] = CRYPTO_ALG_FLAG_SUPPORTED;
    1163           0 :         algs[CRYPTO_ESN] = CRYPTO_ALG_FLAG_SUPPORTED;
    1164             : 
    1165           0 :         crypto_register(swcr_id, algs, swcr_newsession,
    1166             :             swcr_freesession, swcr_process);
    1167           0 : }

Generated by: LCOV version 1.13