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