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