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