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