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