This source file includes following definitions.
- swcr_encdec
- swcr_authcompute
- swcr_compdec
- swcr_newsession
- swcr_freesession
- swcr_process
- swcr_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #include <sys/param.h>
25 #include <sys/systm.h>
26 #include <sys/malloc.h>
27 #include <sys/mbuf.h>
28 #include <sys/sysctl.h>
29 #include <sys/errno.h>
30 #include <dev/rndvar.h>
31 #include <crypto/md5.h>
32 #include <crypto/sha1.h>
33 #include <crypto/rmd160.h>
34 #include <crypto/cast.h>
35 #include <crypto/skipjack.h>
36 #include <crypto/blf.h>
37 #include <crypto/cryptodev.h>
38 #include <crypto/cryptosoft.h>
39 #include <crypto/xform.h>
40
41 u_int8_t hmac_ipad_buffer[64] = {
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 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
50 };
51
52 u_int8_t hmac_opad_buffer[64] = {
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 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C
61 };
62
63
64 struct swcr_data **swcr_sessions = NULL;
65 u_int32_t swcr_sesnum = 0;
66 int32_t swcr_id = -1;
67
68 #define COPYBACK(x, a, b, c, d) \
69 (x) == CRYPTO_BUF_MBUF ? m_copyback((struct mbuf *)a,b,c,d) \
70 : cuio_copyback((struct uio *)a,b,c,d)
71 #define COPYDATA(x, a, b, c, d) \
72 (x) == CRYPTO_BUF_MBUF ? m_copydata((struct mbuf *)a,b,c,d) \
73 : cuio_copydata((struct uio *)a,b,c,d)
74
75
76
77
78 int
79 swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
80 int outtype)
81 {
82 unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN], *idat;
83 unsigned char *ivp, piv[EALG_MAX_BLOCK_LEN];
84 struct enc_xform *exf;
85 int i, k, j, blks, ind, count, ivlen;
86 struct mbuf *m = NULL;
87 struct uio *uio = NULL;
88
89 exf = sw->sw_exf;
90 blks = exf->blocksize;
91 ivlen = exf->ivsize;
92
93
94 if (crd->crd_len % blks)
95 return EINVAL;
96
97 if (outtype == CRYPTO_BUF_MBUF)
98 m = (struct mbuf *) buf;
99 else
100 uio = (struct uio *) buf;
101
102
103 if (crd->crd_flags & CRD_F_ENCRYPT) {
104
105 if (crd->crd_flags & CRD_F_IV_EXPLICIT)
106 bcopy(crd->crd_iv, iv, ivlen);
107 else
108 arc4random_bytes(iv, ivlen);
109
110
111 if (!(crd->crd_flags & CRD_F_IV_PRESENT)) {
112 COPYBACK(outtype, buf, crd->crd_inject, ivlen, iv);
113 }
114
115 } else {
116
117 if (crd->crd_flags & CRD_F_IV_EXPLICIT)
118 bcopy(crd->crd_iv, iv, ivlen);
119 else {
120
121 COPYDATA(outtype, buf, crd->crd_inject, ivlen, iv);
122 }
123 }
124
125 ivp = iv;
126
127 if (exf->reinit)
128 exf->reinit(sw->sw_kschedule, iv);
129
130 if (outtype == CRYPTO_BUF_MBUF) {
131
132 m = m_getptr(m, crd->crd_skip, &k);
133 if (m == NULL)
134 return EINVAL;
135
136 i = crd->crd_len;
137
138 while (i > 0) {
139
140
141
142
143 if (m->m_len < k + blks && m->m_len != k) {
144 m_copydata(m, k, blks, blk);
145
146
147 if (exf->reinit) {
148 exf->encrypt(sw->sw_kschedule, blk);
149 } else if (crd->crd_flags & CRD_F_ENCRYPT) {
150
151 for (j = 0; j < blks; j++)
152 blk[j] ^= ivp[j];
153
154 exf->encrypt(sw->sw_kschedule, blk);
155
156
157
158
159
160 bcopy(blk, iv, blks);
161 ivp = iv;
162 } else {
163
164
165
166
167 if (ivp == iv)
168 bcopy(blk, piv, blks);
169 else
170 bcopy(blk, iv, blks);
171
172 exf->decrypt(sw->sw_kschedule, blk);
173
174
175 for (j = 0; j < blks; j++)
176 blk[j] ^= ivp[j];
177
178 if (ivp == iv)
179 bcopy(piv, iv, blks);
180 else
181 ivp = iv;
182 }
183
184
185 m_copyback(m, k, blks, blk);
186
187
188 m = m_getptr(m, k + blks, &k);
189 if (m == NULL)
190 return EINVAL;
191
192 i -= blks;
193
194
195 if (i == 0)
196 break;
197 }
198
199
200 if (k == m->m_len) {
201 for (m = m->m_next; m && m->m_len == 0;
202 m = m->m_next)
203 ;
204 k = 0;
205 }
206
207
208 if (m == NULL)
209 return EINVAL;
210
211
212
213
214
215
216 idat = mtod(m, unsigned char *) + k;
217
218 while (m->m_len >= k + blks && i > 0) {
219 if (exf->reinit) {
220 exf->encrypt(sw->sw_kschedule, idat);
221 } else if (crd->crd_flags & CRD_F_ENCRYPT) {
222
223 for (j = 0; j < blks; j++)
224 idat[j] ^= ivp[j];
225
226 exf->encrypt(sw->sw_kschedule, idat);
227 ivp = idat;
228 } else {
229
230
231
232
233 if (ivp == iv)
234 bcopy(idat, piv, blks);
235 else
236 bcopy(idat, iv, blks);
237
238 exf->decrypt(sw->sw_kschedule, idat);
239
240
241 for (j = 0; j < blks; j++)
242 idat[j] ^= ivp[j];
243
244 if (ivp == iv)
245 bcopy(piv, iv, blks);
246 else
247 ivp = iv;
248 }
249
250 idat += blks;
251 k += blks;
252 i -= blks;
253 }
254 }
255 } else {
256
257 count = crd->crd_skip;
258 ind = cuio_getptr(uio, count, &k);
259 if (ind == -1)
260 return EINVAL;
261
262 i = crd->crd_len;
263
264 while (i > 0) {
265
266
267
268
269 if (uio->uio_iov[ind].iov_len < k + blks &&
270 uio->uio_iov[ind].iov_len != k) {
271 cuio_copydata(uio, k, blks, blk);
272
273
274 if (exf->reinit) {
275 exf->encrypt(sw->sw_kschedule, blk);
276 } else if (crd->crd_flags & CRD_F_ENCRYPT) {
277
278 for (j = 0; j < blks; j++)
279 blk[j] ^= ivp[j];
280
281 exf->encrypt(sw->sw_kschedule, blk);
282
283
284
285
286
287 bcopy(blk, iv, blks);
288 ivp = iv;
289 } else {
290
291
292
293
294 if (ivp == iv)
295 bcopy(blk, piv, blks);
296 else
297 bcopy(blk, iv, blks);
298
299 exf->decrypt(sw->sw_kschedule, blk);
300
301
302 for (j = 0; j < blks; j++)
303 blk[j] ^= ivp[j];
304
305 if (ivp == iv)
306 bcopy(piv, iv, blks);
307 else
308 ivp = iv;
309 }
310
311
312 cuio_copyback(uio, k, blks, blk);
313
314 count += blks;
315
316
317 ind = cuio_getptr(uio, count, &k);
318 if (ind == -1)
319 return (EINVAL);
320
321 i -= blks;
322
323
324 if (i == 0)
325 break;
326 }
327
328
329
330
331
332
333 idat = (char *)uio->uio_iov[ind].iov_base + k;
334
335 while (uio->uio_iov[ind].iov_len >= k + blks &&
336 i > 0) {
337 if (exf->reinit) {
338 exf->encrypt(sw->sw_kschedule, idat);
339 } else if (crd->crd_flags & CRD_F_ENCRYPT) {
340
341 for (j = 0; j < blks; j++)
342 idat[j] ^= ivp[j];
343
344 exf->encrypt(sw->sw_kschedule, idat);
345 ivp = idat;
346 } else {
347
348
349
350
351 if (ivp == iv)
352 bcopy(idat, piv, blks);
353 else
354 bcopy(idat, iv, blks);
355
356 exf->decrypt(sw->sw_kschedule, idat);
357
358
359 for (j = 0; j < blks; j++)
360 idat[j] ^= ivp[j];
361
362 if (ivp == iv)
363 bcopy(piv, iv, blks);
364 else
365 ivp = iv;
366 }
367
368 idat += blks;
369 count += blks;
370 k += blks;
371 i -= blks;
372 }
373 }
374 }
375
376 return 0;
377 }
378
379
380
381
382 int
383 swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
384 struct swcr_data *sw, caddr_t buf, int outtype)
385 {
386 unsigned char aalg[AALG_MAX_RESULT_LEN];
387 struct auth_hash *axf;
388 union authctx ctx;
389 int err;
390
391 if (sw->sw_ictx == 0)
392 return EINVAL;
393
394 axf = sw->sw_axf;
395
396 bcopy(sw->sw_ictx, &ctx, axf->ctxsize);
397
398 if (outtype == CRYPTO_BUF_MBUF)
399 err = m_apply((struct mbuf *) buf, crd->crd_skip, crd->crd_len,
400 (int (*)(caddr_t, caddr_t, unsigned int)) axf->Update,
401 (caddr_t) &ctx);
402 else
403 err = cuio_apply((struct uio *) buf, crd->crd_skip,
404 crd->crd_len,
405 (int (*)(caddr_t, caddr_t, unsigned int)) axf->Update,
406 (caddr_t) &ctx);
407
408 if (err)
409 return err;
410
411 switch (sw->sw_alg) {
412 case CRYPTO_MD5_HMAC:
413 case CRYPTO_SHA1_HMAC:
414 case CRYPTO_RIPEMD160_HMAC:
415 case CRYPTO_SHA2_256_HMAC:
416 case CRYPTO_SHA2_384_HMAC:
417 case CRYPTO_SHA2_512_HMAC:
418 if (sw->sw_octx == NULL)
419 return EINVAL;
420
421 axf->Final(aalg, &ctx);
422 bcopy(sw->sw_octx, &ctx, axf->ctxsize);
423 axf->Update(&ctx, aalg, axf->hashsize);
424 axf->Final(aalg, &ctx);
425 break;
426
427 case CRYPTO_MD5_KPDK:
428 case CRYPTO_SHA1_KPDK:
429 if (sw->sw_octx == NULL)
430 return EINVAL;
431
432 axf->Update(&ctx, sw->sw_octx, sw->sw_klen);
433 axf->Final(aalg, &ctx);
434 break;
435
436 case CRYPTO_MD5:
437 case CRYPTO_SHA1:
438 axf->Final(aalg, &ctx);
439 break;
440 }
441
442
443 if (outtype == CRYPTO_BUF_MBUF)
444 COPYBACK(outtype, buf, crd->crd_inject, axf->authsize, aalg);
445 else
446 bcopy(aalg, crp->crp_mac, axf->authsize);
447
448 return 0;
449 }
450
451
452
453
454 int
455 swcr_compdec(struct cryptodesc *crd, struct swcr_data *sw,
456 caddr_t buf, int outtype)
457 {
458 u_int8_t *data, *out;
459 struct comp_algo *cxf;
460 int adj;
461 u_int32_t result;
462
463 cxf = sw->sw_cxf;
464
465
466
467
468
469
470 MALLOC(data, u_int8_t *, crd->crd_len, M_CRYPTO_DATA, M_NOWAIT);
471 if (data == NULL)
472 return (EINVAL);
473 COPYDATA(outtype, buf, crd->crd_skip, crd->crd_len, data);
474
475 if (crd->crd_flags & CRD_F_COMP)
476 result = cxf->compress(data, crd->crd_len, &out);
477 else
478 result = cxf->decompress(data, crd->crd_len, &out);
479
480 FREE(data, M_CRYPTO_DATA);
481 if (result == 0)
482 return EINVAL;
483
484
485
486
487 sw->sw_size = result;
488
489 if (crd->crd_flags & CRD_F_COMP) {
490 if (result > crd->crd_len) {
491
492 FREE(out, M_CRYPTO_DATA);
493 return 0;
494 }
495 }
496
497 COPYBACK(outtype, buf, crd->crd_skip, result, out);
498 if (result < crd->crd_len) {
499 adj = result - crd->crd_len;
500 if (outtype == CRYPTO_BUF_MBUF) {
501 adj = result - crd->crd_len;
502 m_adj((struct mbuf *)buf, adj);
503 } else {
504 struct uio *uio = (struct uio *)buf;
505 int ind;
506
507 adj = crd->crd_len - result;
508 ind = uio->uio_iovcnt - 1;
509
510 while (adj > 0 && ind >= 0) {
511 if (adj < uio->uio_iov[ind].iov_len) {
512 uio->uio_iov[ind].iov_len -= adj;
513 break;
514 }
515
516 adj -= uio->uio_iov[ind].iov_len;
517 uio->uio_iov[ind].iov_len = 0;
518 ind--;
519 uio->uio_iovcnt--;
520 }
521 }
522 }
523 FREE(out, M_CRYPTO_DATA);
524 return 0;
525 }
526
527
528
529
530 int
531 swcr_newsession(u_int32_t *sid, struct cryptoini *cri)
532 {
533 struct swcr_data **swd;
534 struct auth_hash *axf;
535 struct enc_xform *txf;
536 struct comp_algo *cxf;
537 u_int32_t i;
538 int k;
539
540 if (sid == NULL || cri == NULL)
541 return EINVAL;
542
543 if (swcr_sessions) {
544 for (i = 1; i < swcr_sesnum; i++)
545 if (swcr_sessions[i] == NULL)
546 break;
547 }
548
549 if (swcr_sessions == NULL || i == swcr_sesnum) {
550 if (swcr_sessions == NULL) {
551 i = 1;
552 swcr_sesnum = CRYPTO_SW_SESSIONS;
553 } else
554 swcr_sesnum *= 2;
555
556 swd = malloc(swcr_sesnum * sizeof(struct swcr_data *),
557 M_CRYPTO_DATA, M_NOWAIT);
558 if (swd == NULL) {
559
560 if (swcr_sesnum == CRYPTO_SW_SESSIONS)
561 swcr_sesnum = 0;
562 else
563 swcr_sesnum /= 2;
564 return ENOBUFS;
565 }
566
567 bzero(swd, swcr_sesnum * sizeof(struct swcr_data *));
568
569
570 if (swcr_sessions) {
571 bcopy(swcr_sessions, swd,
572 (swcr_sesnum / 2) * sizeof(struct swcr_data *));
573 free(swcr_sessions, M_CRYPTO_DATA);
574 }
575
576 swcr_sessions = swd;
577 }
578
579 swd = &swcr_sessions[i];
580 *sid = i;
581
582 while (cri) {
583 MALLOC(*swd, struct swcr_data *, sizeof(struct swcr_data),
584 M_CRYPTO_DATA, M_NOWAIT);
585 if (*swd == NULL) {
586 swcr_freesession(i);
587 return ENOBUFS;
588 }
589 bzero(*swd, sizeof(struct swcr_data));
590
591 switch (cri->cri_alg) {
592 case CRYPTO_DES_CBC:
593 txf = &enc_xform_des;
594 goto enccommon;
595 case CRYPTO_3DES_CBC:
596 txf = &enc_xform_3des;
597 goto enccommon;
598 case CRYPTO_BLF_CBC:
599 txf = &enc_xform_blf;
600 goto enccommon;
601 case CRYPTO_CAST_CBC:
602 txf = &enc_xform_cast5;
603 goto enccommon;
604 case CRYPTO_SKIPJACK_CBC:
605 txf = &enc_xform_skipjack;
606 goto enccommon;
607 case CRYPTO_RIJNDAEL128_CBC:
608 txf = &enc_xform_rijndael128;
609 goto enccommon;
610 case CRYPTO_AES_CTR:
611 txf = &enc_xform_aes_ctr;
612 goto enccommon;
613 case CRYPTO_NULL:
614 txf = &enc_xform_null;
615 goto enccommon;
616 enccommon:
617 if (txf->setkey(&((*swd)->sw_kschedule), cri->cri_key,
618 cri->cri_klen / 8) < 0) {
619 swcr_freesession(i);
620 return EINVAL;
621 }
622 (*swd)->sw_exf = txf;
623 break;
624
625 case CRYPTO_MD5_HMAC:
626 axf = &auth_hash_hmac_md5_96;
627 goto authcommon;
628 case CRYPTO_SHA1_HMAC:
629 axf = &auth_hash_hmac_sha1_96;
630 goto authcommon;
631 case CRYPTO_RIPEMD160_HMAC:
632 axf = &auth_hash_hmac_ripemd_160_96;
633 goto authcommon;
634 case CRYPTO_SHA2_256_HMAC:
635 axf = &auth_hash_hmac_sha2_256_96;
636 goto authcommon;
637 case CRYPTO_SHA2_384_HMAC:
638 axf = &auth_hash_hmac_sha2_384_96;
639 goto authcommon;
640 case CRYPTO_SHA2_512_HMAC:
641 axf = &auth_hash_hmac_sha2_512_96;
642 authcommon:
643 (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
644 M_NOWAIT);
645 if ((*swd)->sw_ictx == NULL) {
646 swcr_freesession(i);
647 return ENOBUFS;
648 }
649
650 (*swd)->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA,
651 M_NOWAIT);
652 if ((*swd)->sw_octx == NULL) {
653 swcr_freesession(i);
654 return ENOBUFS;
655 }
656
657 for (k = 0; k < cri->cri_klen / 8; k++)
658 cri->cri_key[k] ^= HMAC_IPAD_VAL;
659
660 axf->Init((*swd)->sw_ictx);
661 axf->Update((*swd)->sw_ictx, cri->cri_key,
662 cri->cri_klen / 8);
663 axf->Update((*swd)->sw_ictx, hmac_ipad_buffer,
664 HMAC_BLOCK_LEN - (cri->cri_klen / 8));
665
666 for (k = 0; k < cri->cri_klen / 8; k++)
667 cri->cri_key[k] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
668
669 axf->Init((*swd)->sw_octx);
670 axf->Update((*swd)->sw_octx, cri->cri_key,
671 cri->cri_klen / 8);
672 axf->Update((*swd)->sw_octx, hmac_opad_buffer,
673 HMAC_BLOCK_LEN - (cri->cri_klen / 8));
674
675 for (k = 0; k < cri->cri_klen / 8; k++)
676 cri->cri_key[k] ^= HMAC_OPAD_VAL;
677 (*swd)->sw_axf = axf;
678 break;
679
680 case CRYPTO_MD5_KPDK:
681 axf = &auth_hash_key_md5;
682 goto auth2common;
683
684 case CRYPTO_SHA1_KPDK:
685 axf = &auth_hash_key_sha1;
686 auth2common:
687 (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
688 M_NOWAIT);
689 if ((*swd)->sw_ictx == NULL) {
690 swcr_freesession(i);
691 return ENOBUFS;
692 }
693
694
695 (*swd)->sw_octx = malloc(cri->cri_klen / 8, M_CRYPTO_DATA,
696 M_NOWAIT);
697 if ((*swd)->sw_octx == NULL) {
698 swcr_freesession(i);
699 return ENOBUFS;
700 }
701
702 (*swd)->sw_klen = cri->cri_klen / 8;
703 bcopy(cri->cri_key, (*swd)->sw_octx, cri->cri_klen / 8);
704 axf->Init((*swd)->sw_ictx);
705 axf->Update((*swd)->sw_ictx, cri->cri_key,
706 cri->cri_klen / 8);
707 axf->Final(NULL, (*swd)->sw_ictx);
708 (*swd)->sw_axf = axf;
709 break;
710
711 case CRYPTO_MD5:
712 axf = &auth_hash_md5;
713 goto auth3common;
714
715 case CRYPTO_SHA1:
716 axf = &auth_hash_sha1;
717 auth3common:
718 (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
719 M_NOWAIT);
720 if ((*swd)->sw_ictx == NULL) {
721 swcr_freesession(i);
722 return ENOBUFS;
723 }
724
725 axf->Init((*swd)->sw_ictx);
726 (*swd)->sw_axf = axf;
727 break;
728
729 case CRYPTO_DEFLATE_COMP:
730 cxf = &comp_algo_deflate;
731 (*swd)->sw_cxf = cxf;
732 break;
733 default:
734 swcr_freesession(i);
735 return EINVAL;
736 }
737
738 (*swd)->sw_alg = cri->cri_alg;
739 cri = cri->cri_next;
740 swd = &((*swd)->sw_next);
741 }
742 return 0;
743 }
744
745
746
747
748 int
749 swcr_freesession(u_int64_t tid)
750 {
751 struct swcr_data *swd;
752 struct enc_xform *txf;
753 struct auth_hash *axf;
754 u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
755
756 if (sid > swcr_sesnum || swcr_sessions == NULL ||
757 swcr_sessions[sid] == NULL)
758 return EINVAL;
759
760
761 if (sid == 0)
762 return 0;
763
764 while ((swd = swcr_sessions[sid]) != NULL) {
765 swcr_sessions[sid] = swd->sw_next;
766
767 switch (swd->sw_alg) {
768 case CRYPTO_DES_CBC:
769 case CRYPTO_3DES_CBC:
770 case CRYPTO_BLF_CBC:
771 case CRYPTO_CAST_CBC:
772 case CRYPTO_SKIPJACK_CBC:
773 case CRYPTO_RIJNDAEL128_CBC:
774 case CRYPTO_AES_CTR:
775 case CRYPTO_NULL:
776 txf = swd->sw_exf;
777
778 if (swd->sw_kschedule)
779 txf->zerokey(&(swd->sw_kschedule));
780 break;
781
782 case CRYPTO_MD5_HMAC:
783 case CRYPTO_SHA1_HMAC:
784 case CRYPTO_RIPEMD160_HMAC:
785 case CRYPTO_SHA2_256_HMAC:
786 case CRYPTO_SHA2_384_HMAC:
787 case CRYPTO_SHA2_512_HMAC:
788 axf = swd->sw_axf;
789
790 if (swd->sw_ictx) {
791 bzero(swd->sw_ictx, axf->ctxsize);
792 free(swd->sw_ictx, M_CRYPTO_DATA);
793 }
794 if (swd->sw_octx) {
795 bzero(swd->sw_octx, axf->ctxsize);
796 free(swd->sw_octx, M_CRYPTO_DATA);
797 }
798 break;
799
800 case CRYPTO_MD5_KPDK:
801 case CRYPTO_SHA1_KPDK:
802 axf = swd->sw_axf;
803
804 if (swd->sw_ictx) {
805 bzero(swd->sw_ictx, axf->ctxsize);
806 free(swd->sw_ictx, M_CRYPTO_DATA);
807 }
808 if (swd->sw_octx) {
809 bzero(swd->sw_octx, swd->sw_klen);
810 free(swd->sw_octx, M_CRYPTO_DATA);
811 }
812 break;
813
814 case CRYPTO_MD5:
815 case CRYPTO_SHA1:
816 axf = swd->sw_axf;
817
818 if (swd->sw_ictx)
819 free(swd->sw_ictx, M_CRYPTO_DATA);
820 break;
821 }
822
823 FREE(swd, M_CRYPTO_DATA);
824 }
825 return 0;
826 }
827
828
829
830
831 int
832 swcr_process(struct cryptop *crp)
833 {
834 struct cryptodesc *crd;
835 struct swcr_data *sw;
836 u_int32_t lid;
837 int type;
838
839
840 if (crp == NULL)
841 return EINVAL;
842
843 if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
844 crp->crp_etype = EINVAL;
845 goto done;
846 }
847
848 lid = crp->crp_sid & 0xffffffff;
849 if (lid >= swcr_sesnum || lid == 0 || swcr_sessions[lid] == NULL) {
850 crp->crp_etype = ENOENT;
851 goto done;
852 }
853
854 if (crp->crp_flags & CRYPTO_F_IMBUF)
855 type = CRYPTO_BUF_MBUF;
856 else
857 type = CRYPTO_BUF_IOV;
858
859
860 for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
861
862
863
864
865
866
867
868
869
870
871 for (sw = swcr_sessions[lid];
872 sw && sw->sw_alg != crd->crd_alg;
873 sw = sw->sw_next)
874 ;
875
876
877 if (sw == NULL) {
878 crp->crp_etype = EINVAL;
879 goto done;
880 }
881
882 switch (sw->sw_alg) {
883 case CRYPTO_NULL:
884 break;
885 case CRYPTO_DES_CBC:
886 case CRYPTO_3DES_CBC:
887 case CRYPTO_BLF_CBC:
888 case CRYPTO_CAST_CBC:
889 case CRYPTO_SKIPJACK_CBC:
890 case CRYPTO_RIJNDAEL128_CBC:
891 case CRYPTO_AES_CTR:
892 if ((crp->crp_etype = swcr_encdec(crd, sw,
893 crp->crp_buf, type)) != 0)
894 goto done;
895 break;
896 case CRYPTO_MD5_HMAC:
897 case CRYPTO_SHA1_HMAC:
898 case CRYPTO_RIPEMD160_HMAC:
899 case CRYPTO_SHA2_256_HMAC:
900 case CRYPTO_SHA2_384_HMAC:
901 case CRYPTO_SHA2_512_HMAC:
902 case CRYPTO_MD5_KPDK:
903 case CRYPTO_SHA1_KPDK:
904 case CRYPTO_MD5:
905 case CRYPTO_SHA1:
906 if ((crp->crp_etype = swcr_authcompute(crp, crd, sw,
907 crp->crp_buf, type)) != 0)
908 goto done;
909 break;
910
911 case CRYPTO_DEFLATE_COMP:
912 if ((crp->crp_etype = swcr_compdec(crd, sw,
913 crp->crp_buf, type)) != 0)
914 goto done;
915 else
916 crp->crp_olen = (int)sw->sw_size;
917 break;
918
919 default:
920
921 crp->crp_etype = EINVAL;
922 goto done;
923 }
924 }
925
926 done:
927 crypto_done(crp);
928 return 0;
929 }
930
931
932
933
934 void
935 swcr_init(void)
936 {
937 int algs[CRYPTO_ALGORITHM_MAX + 1];
938 int flags = CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_ENCRYPT_MAC |
939 CRYPTOCAP_F_MAC_ENCRYPT;
940
941 swcr_id = crypto_get_driverid(flags);
942 if (swcr_id < 0) {
943
944 panic("Software crypto device cannot initialize!");
945 }
946
947 bzero(algs, sizeof(algs));
948
949 algs[CRYPTO_DES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
950 algs[CRYPTO_3DES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
951 algs[CRYPTO_BLF_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
952 algs[CRYPTO_CAST_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
953 algs[CRYPTO_SKIPJACK_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
954 algs[CRYPTO_MD5_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
955 algs[CRYPTO_SHA1_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
956 algs[CRYPTO_RIPEMD160_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
957 algs[CRYPTO_MD5_KPDK] = CRYPTO_ALG_FLAG_SUPPORTED;
958 algs[CRYPTO_SHA1_KPDK] = CRYPTO_ALG_FLAG_SUPPORTED;
959 algs[CRYPTO_MD5] = CRYPTO_ALG_FLAG_SUPPORTED;
960 algs[CRYPTO_SHA1] = CRYPTO_ALG_FLAG_SUPPORTED;
961 algs[CRYPTO_RIJNDAEL128_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
962 algs[CRYPTO_AES_CTR] = CRYPTO_ALG_FLAG_SUPPORTED;
963 algs[CRYPTO_DEFLATE_COMP] = CRYPTO_ALG_FLAG_SUPPORTED;
964 algs[CRYPTO_NULL] = CRYPTO_ALG_FLAG_SUPPORTED;
965 algs[CRYPTO_SHA2_256_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
966 algs[CRYPTO_SHA2_384_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
967 algs[CRYPTO_SHA2_512_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
968
969 crypto_register(swcr_id, algs, swcr_newsession,
970 swcr_freesession, swcr_process);
971 }