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