1 /* $OpenBSD: cryptosoft.c,v 1.35 2002/04/26 08:43:50 deraadt Exp $ */
2
3 /*-
4 * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
5 *
6 * This code was written by Angelos D. Keromytis in Athens, Greece, in
7 * February 2000. Network Security Technologies Inc. (NSTI) kindly
8 * supported the development of this code.
9 *
10 * Copyright (c) 2000, 2001 Angelos D. Keromytis
11 *
12 * Permission to use, copy, and modify this software with or without fee
13 * is hereby granted, provided that this entire notice is included in
14 * all source code copies of any software which is or includes a copy or
15 * modification of this software.
16 *
17 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
18 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
19 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
20 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
21 * PURPOSE.
22 */
23
24 #include <sys/cdefs.h>
25 __FBSDID("$FreeBSD: releng/6.2/sys/opencrypto/cryptosoft.c 161998 2006-09-04 15:16:14Z pjd $");
26
27 #include <sys/param.h>
28 #include <sys/systm.h>
29 #include <sys/malloc.h>
30 #include <sys/mbuf.h>
31 #include <sys/sysctl.h>
32 #include <sys/errno.h>
33 #include <sys/random.h>
34 #include <sys/kernel.h>
35 #include <sys/uio.h>
36
37 #include <crypto/blowfish/blowfish.h>
38 #include <crypto/sha1.h>
39 #include <opencrypto/rmd160.h>
40 #include <opencrypto/cast.h>
41 #include <opencrypto/skipjack.h>
42 #include <sys/md5.h>
43
44 #include <opencrypto/cryptodev.h>
45 #include <opencrypto/cryptosoft.h>
46 #include <opencrypto/xform.h>
47
48 u_int8_t *hmac_ipad_buffer;
49 u_int8_t *hmac_opad_buffer;
50
51 struct swcr_data **swcr_sessions = NULL;
52 u_int32_t swcr_sesnum = 0;
53 int32_t swcr_id = -1;
54
55 static int swcr_encdec(struct cryptodesc *, struct swcr_data *, caddr_t, int);
56 static int swcr_authcompute(struct cryptodesc *, struct swcr_data *, caddr_t, int);
57 static int swcr_compdec(struct cryptodesc *, struct swcr_data *, caddr_t, int);
58 static int swcr_process(void *, struct cryptop *, int);
59 static int swcr_newsession(void *, u_int32_t *, struct cryptoini *);
60 static int swcr_freesession(void *, u_int64_t);
61
62 /*
63 * Apply a symmetric encryption/decryption algorithm.
64 */
65 static int
66 swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
67 int flags)
68 {
69 unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN], *idat;
70 unsigned char *ivp, piv[EALG_MAX_BLOCK_LEN];
71 struct enc_xform *exf;
72 int i, k, j, blks;
73
74 exf = sw->sw_exf;
75 blks = exf->blocksize;
76
77 /* Check for non-padded data */
78 if (crd->crd_len % blks)
79 return EINVAL;
80
81 /* Initialize the IV */
82 if (crd->crd_flags & CRD_F_ENCRYPT) {
83 /* IV explicitly provided ? */
84 if (crd->crd_flags & CRD_F_IV_EXPLICIT)
85 bcopy(crd->crd_iv, iv, blks);
86 else
87 arc4rand(iv, blks, 0);
88
89 /* Do we need to write the IV */
90 if (!(crd->crd_flags & CRD_F_IV_PRESENT))
91 crypto_copyback(flags, buf, crd->crd_inject, blks, iv);
92
93 } else { /* Decryption */
94 /* IV explicitly provided ? */
95 if (crd->crd_flags & CRD_F_IV_EXPLICIT)
96 bcopy(crd->crd_iv, iv, blks);
97 else {
98 /* Get IV off buf */
99 crypto_copydata(flags, buf, crd->crd_inject, blks, iv);
100 }
101 }
102
103 if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {
104 int error;
105
106 if (sw->sw_kschedule)
107 exf->zerokey(&(sw->sw_kschedule));
108 error = exf->setkey(&sw->sw_kschedule,
109 crd->crd_key, crd->crd_klen / 8);
110 if (error)
111 return (error);
112 }
113 ivp = iv;
114
115 if (flags & CRYPTO_F_IMBUF) {
116 struct mbuf *m = (struct mbuf *) buf;
117
118 /* Find beginning of data */
119 m = m_getptr(m, crd->crd_skip, &k);
120 if (m == NULL)
121 return EINVAL;
122
123 i = crd->crd_len;
124
125 while (i > 0) {
126 /*
127 * If there's insufficient data at the end of
128 * an mbuf, we have to do some copying.
129 */
130 if (m->m_len < k + blks && m->m_len != k) {
131 m_copydata(m, k, blks, blk);
132
133 /* Actual encryption/decryption */
134 if (crd->crd_flags & CRD_F_ENCRYPT) {
135 /* XOR with previous block */
136 for (j = 0; j < blks; j++)
137 blk[j] ^= ivp[j];
138
139 exf->encrypt(sw->sw_kschedule, blk);
140
141 /*
142 * Keep encrypted block for XOR'ing
143 * with next block
144 */
145 bcopy(blk, iv, blks);
146 ivp = iv;
147 } else { /* decrypt */
148 /*
149 * Keep encrypted block for XOR'ing
150 * with next block
151 */
152 if (ivp == iv)
153 bcopy(blk, piv, blks);
154 else
155 bcopy(blk, iv, blks);
156
157 exf->decrypt(sw->sw_kschedule, blk);
158
159 /* XOR with previous block */
160 for (j = 0; j < blks; j++)
161 blk[j] ^= ivp[j];
162
163 if (ivp == iv)
164 bcopy(piv, iv, blks);
165 else
166 ivp = iv;
167 }
168
169 /* Copy back decrypted block */
170 m_copyback(m, k, blks, blk);
171
172 /* Advance pointer */
173 m = m_getptr(m, k + blks, &k);
174 if (m == NULL)
175 return EINVAL;
176
177 i -= blks;
178
179 /* Could be done... */
180 if (i == 0)
181 break;
182 }
183
184 /* Skip possibly empty mbufs */
185 if (k == m->m_len) {
186 for (m = m->m_next; m && m->m_len == 0;
187 m = m->m_next)
188 ;
189 k = 0;
190 }
191
192 /* Sanity check */
193 if (m == NULL)
194 return EINVAL;
195
196 /*
197 * Warning: idat may point to garbage here, but
198 * we only use it in the while() loop, only if
199 * there are indeed enough data.
200 */
201 idat = mtod(m, unsigned char *) + k;
202
203 while (m->m_len >= k + blks && i > 0) {
204 if (crd->crd_flags & CRD_F_ENCRYPT) {
205 /* XOR with previous block/IV */
206 for (j = 0; j < blks; j++)
207 idat[j] ^= ivp[j];
208
209 exf->encrypt(sw->sw_kschedule, idat);
210 ivp = idat;
211 } else { /* decrypt */
212 /*
213 * Keep encrypted block to be used
214 * in next block's processing.
215 */
216 if (ivp == iv)
217 bcopy(idat, piv, blks);
218 else
219 bcopy(idat, iv, blks);
220
221 exf->decrypt(sw->sw_kschedule, idat);
222
223 /* XOR with previous block/IV */
224 for (j = 0; j < blks; j++)
225 idat[j] ^= ivp[j];
226
227 if (ivp == iv)
228 bcopy(piv, iv, blks);
229 else
230 ivp = iv;
231 }
232
233 idat += blks;
234 k += blks;
235 i -= blks;
236 }
237 }
238
239 return 0; /* Done with mbuf encryption/decryption */
240 } else if (flags & CRYPTO_F_IOV) {
241 struct uio *uio = (struct uio *) buf;
242 struct iovec *iov;
243
244 /* Find beginning of data */
245 iov = cuio_getptr(uio, crd->crd_skip, &k);
246 if (iov == NULL)
247 return EINVAL;
248
249 i = crd->crd_len;
250
251 while (i > 0) {
252 /*
253 * If there's insufficient data at the end of
254 * an iovec, we have to do some copying.
255 */
256 if (iov->iov_len < k + blks && iov->iov_len != k) {
257 cuio_copydata(uio, k, blks, blk);
258
259 /* Actual encryption/decryption */
260 if (crd->crd_flags & CRD_F_ENCRYPT) {
261 /* XOR with previous block */
262 for (j = 0; j < blks; j++)
263 blk[j] ^= ivp[j];
264
265 exf->encrypt(sw->sw_kschedule, blk);
266
267 /*
268 * Keep encrypted block for XOR'ing
269 * with next block
270 */
271 bcopy(blk, iv, blks);
272 ivp = iv;
273 } else { /* decrypt */
274 /*
275 * Keep encrypted block for XOR'ing
276 * with next block
277 */
278 if (ivp == iv)
279 bcopy(blk, piv, blks);
280 else
281 bcopy(blk, iv, blks);
282
283 exf->decrypt(sw->sw_kschedule, blk);
284
285 /* XOR with previous block */
286 for (j = 0; j < blks; j++)
287 blk[j] ^= ivp[j];
288
289 if (ivp == iv)
290 bcopy(piv, iv, blks);
291 else
292 ivp = iv;
293 }
294
295 /* Copy back decrypted block */
296 cuio_copyback(uio, k, blks, blk);
297
298 /* Advance pointer */
299 iov = cuio_getptr(uio, k + blks, &k);
300 if (iov == NULL)
301 return EINVAL;
302
303 i -= blks;
304
305 /* Could be done... */
306 if (i == 0)
307 break;
308 }
309
310 /*
311 * Warning: idat may point to garbage here, but
312 * we only use it in the while() loop, only if
313 * there are indeed enough data.
314 */
315 idat = (char *)iov->iov_base + k;
316
317 while (iov->iov_len >= k + blks && i > 0) {
318 if (crd->crd_flags & CRD_F_ENCRYPT) {
319 /* XOR with previous block/IV */
320 for (j = 0; j < blks; j++)
321 idat[j] ^= ivp[j];
322
323 exf->encrypt(sw->sw_kschedule, idat);
324 ivp = idat;
325 } else { /* decrypt */
326 /*
327 * Keep encrypted block to be used
328 * in next block's processing.
329 */
330 if (ivp == iv)
331 bcopy(idat, piv, blks);
332 else
333 bcopy(idat, iv, blks);
334
335 exf->decrypt(sw->sw_kschedule, idat);
336
337 /* XOR with previous block/IV */
338 for (j = 0; j < blks; j++)
339 idat[j] ^= ivp[j];
340
341 if (ivp == iv)
342 bcopy(piv, iv, blks);
343 else
344 ivp = iv;
345 }
346
347 idat += blks;
348 k += blks;
349 i -= blks;
350 }
351 }
352
353 return 0; /* Done with iovec encryption/decryption */
354 } else { /* contiguous buffer */
355 if (crd->crd_flags & CRD_F_ENCRYPT) {
356 for (i = crd->crd_skip;
357 i < crd->crd_skip + crd->crd_len; i += blks) {
358 /* XOR with the IV/previous block, as appropriate. */
359 if (i == crd->crd_skip)
360 for (k = 0; k < blks; k++)
361 buf[i + k] ^= ivp[k];
362 else
363 for (k = 0; k < blks; k++)
364 buf[i + k] ^= buf[i + k - blks];
365 exf->encrypt(sw->sw_kschedule, buf + i);
366 }
367 } else { /* Decrypt */
368 /*
369 * Start at the end, so we don't need to keep the encrypted
370 * block as the IV for the next block.
371 */
372 for (i = crd->crd_skip + crd->crd_len - blks;
373 i >= crd->crd_skip; i -= blks) {
374 exf->decrypt(sw->sw_kschedule, buf + i);
375
376 /* XOR with the IV/previous block, as appropriate */
377 if (i == crd->crd_skip)
378 for (k = 0; k < blks; k++)
379 buf[i + k] ^= ivp[k];
380 else
381 for (k = 0; k < blks; k++)
382 buf[i + k] ^= buf[i + k - blks];
383 }
384 }
385
386 return 0; /* Done with contiguous buffer encryption/decryption */
387 }
388
389 /* Unreachable */
390 return EINVAL;
391 }
392
393 static void
394 swcr_authprepare(struct auth_hash *axf, struct swcr_data *sw, u_char *key,
395 int klen)
396 {
397 int k;
398
399 klen /= 8;
400
401 switch (axf->type) {
402 case CRYPTO_MD5_HMAC:
403 case CRYPTO_SHA1_HMAC:
404 case CRYPTO_SHA2_256_HMAC:
405 case CRYPTO_SHA2_384_HMAC:
406 case CRYPTO_SHA2_512_HMAC:
407 case CRYPTO_NULL_HMAC:
408 case CRYPTO_RIPEMD160_HMAC:
409 for (k = 0; k < klen; k++)
410 key[k] ^= HMAC_IPAD_VAL;
411
412 axf->Init(sw->sw_ictx);
413 axf->Update(sw->sw_ictx, key, klen);
414 axf->Update(sw->sw_ictx, hmac_ipad_buffer, axf->blocksize - klen);
415
416 for (k = 0; k < klen; k++)
417 key[k] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
418
419 axf->Init(sw->sw_octx);
420 axf->Update(sw->sw_octx, key, klen);
421 axf->Update(sw->sw_octx, hmac_opad_buffer, axf->blocksize - klen);
422
423 for (k = 0; k < klen; k++)
424 key[k] ^= HMAC_OPAD_VAL;
425 break;
426 case CRYPTO_MD5_KPDK:
427 case CRYPTO_SHA1_KPDK:
428 sw->sw_klen = klen;
429 bcopy(key, sw->sw_octx, klen);
430 axf->Init(sw->sw_ictx);
431 axf->Update(sw->sw_ictx, key, klen);
432 axf->Final(NULL, sw->sw_ictx);
433 break;
434 default:
435 printf("%s: CRD_F_KEY_EXPLICIT flag given, but algorithm %d "
436 "doesn't use keys.\n", __func__, axf->type);
437 }
438 }
439
440 /*
441 * Compute keyed-hash authenticator.
442 */
443 static int
444 swcr_authcompute(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
445 int flags)
446 {
447 unsigned char aalg[HASH_MAX_LEN];
448 struct auth_hash *axf;
449 union authctx ctx;
450 int err;
451
452 if (sw->sw_ictx == 0)
453 return EINVAL;
454
455 axf = sw->sw_axf;
456
457 if (crd->crd_flags & CRD_F_KEY_EXPLICIT)
458 swcr_authprepare(axf, sw, crd->crd_key, crd->crd_klen);
459
460 bcopy(sw->sw_ictx, &ctx, axf->ctxsize);
461
462 err = crypto_apply(flags, buf, crd->crd_skip, crd->crd_len,
463 (int (*)(void *, void *, unsigned int))axf->Update, (caddr_t)&ctx);
464 if (err)
465 return err;
466
467 switch (sw->sw_alg) {
468 case CRYPTO_MD5_HMAC:
469 case CRYPTO_SHA1_HMAC:
470 case CRYPTO_SHA2_256_HMAC:
471 case CRYPTO_SHA2_384_HMAC:
472 case CRYPTO_SHA2_512_HMAC:
473 case CRYPTO_RIPEMD160_HMAC:
474 if (sw->sw_octx == NULL)
475 return EINVAL;
476
477 axf->Final(aalg, &ctx);
478 bcopy(sw->sw_octx, &ctx, axf->ctxsize);
479 axf->Update(&ctx, aalg, axf->hashsize);
480 axf->Final(aalg, &ctx);
481 break;
482
483 case CRYPTO_MD5_KPDK:
484 case CRYPTO_SHA1_KPDK:
485 if (sw->sw_octx == NULL)
486 return EINVAL;
487
488 axf->Update(&ctx, sw->sw_octx, sw->sw_klen);
489 axf->Final(aalg, &ctx);
490 break;
491
492 case CRYPTO_NULL_HMAC:
493 axf->Final(aalg, &ctx);
494 break;
495 }
496
497 /* Inject the authentication data */
498 crypto_copyback(flags, buf, crd->crd_inject,
499 sw->sw_mlen == 0 ? axf->hashsize : sw->sw_mlen, aalg);
500 return 0;
501 }
502
503 /*
504 * Apply a compression/decompression algorithm
505 */
506 static int
507 swcr_compdec(struct cryptodesc *crd, struct swcr_data *sw,
508 caddr_t buf, int flags)
509 {
510 u_int8_t *data, *out;
511 struct comp_algo *cxf;
512 int adj;
513 u_int32_t result;
514
515 cxf = sw->sw_cxf;
516
517 /* We must handle the whole buffer of data in one time
518 * then if there is not all the data in the mbuf, we must
519 * copy in a buffer.
520 */
521
522 MALLOC(data, u_int8_t *, crd->crd_len, M_CRYPTO_DATA, M_NOWAIT);
523 if (data == NULL)
524 return (EINVAL);
525 crypto_copydata(flags, buf, crd->crd_skip, crd->crd_len, data);
526
527 if (crd->crd_flags & CRD_F_COMP)
528 result = cxf->compress(data, crd->crd_len, &out);
529 else
530 result = cxf->decompress(data, crd->crd_len, &out);
531
532 FREE(data, M_CRYPTO_DATA);
533 if (result == 0)
534 return EINVAL;
535
536 /* Copy back the (de)compressed data. m_copyback is
537 * extending the mbuf as necessary.
538 */
539 sw->sw_size = result;
540 /* Check the compressed size when doing compression */
541 if (crd->crd_flags & CRD_F_COMP) {
542 if (result > crd->crd_len) {
543 /* Compression was useless, we lost time */
544 FREE(out, M_CRYPTO_DATA);
545 return 0;
546 }
547 }
548
549 crypto_copyback(flags, buf, crd->crd_skip, result, out);
550 if (result < crd->crd_len) {
551 adj = result - crd->crd_len;
552 if (flags & CRYPTO_F_IMBUF) {
553 adj = result - crd->crd_len;
554 m_adj((struct mbuf *)buf, adj);
555 } else if (flags & CRYPTO_F_IOV) {
556 struct uio *uio = (struct uio *)buf;
557 int ind;
558
559 adj = crd->crd_len - result;
560 ind = uio->uio_iovcnt - 1;
561
562 while (adj > 0 && ind >= 0) {
563 if (adj < uio->uio_iov[ind].iov_len) {
564 uio->uio_iov[ind].iov_len -= adj;
565 break;
566 }
567
568 adj -= uio->uio_iov[ind].iov_len;
569 uio->uio_iov[ind].iov_len = 0;
570 ind--;
571 uio->uio_iovcnt--;
572 }
573 }
574 }
575 FREE(out, M_CRYPTO_DATA);
576 return 0;
577 }
578
579 /*
580 * Generate a new software session.
581 */
582 static int
583 swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
584 {
585 struct swcr_data **swd;
586 struct auth_hash *axf;
587 struct enc_xform *txf;
588 struct comp_algo *cxf;
589 u_int32_t i;
590 int error;
591
592 if (sid == NULL || cri == NULL)
593 return EINVAL;
594
595 if (swcr_sessions) {
596 for (i = 1; i < swcr_sesnum; i++)
597 if (swcr_sessions[i] == NULL)
598 break;
599 } else
600 i = 1; /* NB: to silence compiler warning */
601
602 if (swcr_sessions == NULL || i == swcr_sesnum) {
603 if (swcr_sessions == NULL) {
604 i = 1; /* We leave swcr_sessions[0] empty */
605 swcr_sesnum = CRYPTO_SW_SESSIONS;
606 } else
607 swcr_sesnum *= 2;
608
609 swd = malloc(swcr_sesnum * sizeof(struct swcr_data *),
610 M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
611 if (swd == NULL) {
612 /* Reset session number */
613 if (swcr_sesnum == CRYPTO_SW_SESSIONS)
614 swcr_sesnum = 0;
615 else
616 swcr_sesnum /= 2;
617 return ENOBUFS;
618 }
619
620 /* Copy existing sessions */
621 if (swcr_sessions) {
622 bcopy(swcr_sessions, swd,
623 (swcr_sesnum / 2) * sizeof(struct swcr_data *));
624 free(swcr_sessions, M_CRYPTO_DATA);
625 }
626
627 swcr_sessions = swd;
628 }
629
630 swd = &swcr_sessions[i];
631 *sid = i;
632
633 while (cri) {
634 MALLOC(*swd, struct swcr_data *, sizeof(struct swcr_data),
635 M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
636 if (*swd == NULL) {
637 swcr_freesession(NULL, i);
638 return ENOBUFS;
639 }
640
641 switch (cri->cri_alg) {
642 case CRYPTO_DES_CBC:
643 txf = &enc_xform_des;
644 goto enccommon;
645 case CRYPTO_3DES_CBC:
646 txf = &enc_xform_3des;
647 goto enccommon;
648 case CRYPTO_BLF_CBC:
649 txf = &enc_xform_blf;
650 goto enccommon;
651 case CRYPTO_CAST_CBC:
652 txf = &enc_xform_cast5;
653 goto enccommon;
654 case CRYPTO_SKIPJACK_CBC:
655 txf = &enc_xform_skipjack;
656 goto enccommon;
657 case CRYPTO_RIJNDAEL128_CBC:
658 txf = &enc_xform_rijndael128;
659 goto enccommon;
660 case CRYPTO_NULL_CBC:
661 txf = &enc_xform_null;
662 goto enccommon;
663 enccommon:
664 if (cri->cri_key != NULL) {
665 error = txf->setkey(&((*swd)->sw_kschedule),
666 cri->cri_key, cri->cri_klen / 8);
667 if (error) {
668 swcr_freesession(NULL, i);
669 return error;
670 }
671 }
672 (*swd)->sw_exf = txf;
673 break;
674
675 case CRYPTO_MD5_HMAC:
676 axf = &auth_hash_hmac_md5;
677 goto authcommon;
678 case CRYPTO_SHA1_HMAC:
679 axf = &auth_hash_hmac_sha1;
680 goto authcommon;
681 case CRYPTO_SHA2_256_HMAC:
682 axf = &auth_hash_hmac_sha2_256;
683 goto authcommon;
684 case CRYPTO_SHA2_384_HMAC:
685 axf = &auth_hash_hmac_sha2_384;
686 goto authcommon;
687 case CRYPTO_SHA2_512_HMAC:
688 axf = &auth_hash_hmac_sha2_512;
689 goto authcommon;
690 case CRYPTO_NULL_HMAC:
691 axf = &auth_hash_null;
692 goto authcommon;
693 case CRYPTO_RIPEMD160_HMAC:
694 axf = &auth_hash_hmac_ripemd_160;
695 authcommon:
696 (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
697 M_NOWAIT);
698 if ((*swd)->sw_ictx == NULL) {
699 swcr_freesession(NULL, i);
700 return ENOBUFS;
701 }
702
703 (*swd)->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA,
704 M_NOWAIT);
705 if ((*swd)->sw_octx == NULL) {
706 swcr_freesession(NULL, i);
707 return ENOBUFS;
708 }
709
710 if (cri->cri_key != NULL) {
711 swcr_authprepare(axf, *swd, cri->cri_key,
712 cri->cri_klen);
713 }
714
715 (*swd)->sw_mlen = cri->cri_mlen;
716 (*swd)->sw_axf = axf;
717 break;
718
719 case CRYPTO_MD5_KPDK:
720 axf = &auth_hash_key_md5;
721 goto auth2common;
722
723 case CRYPTO_SHA1_KPDK:
724 axf = &auth_hash_key_sha1;
725 auth2common:
726 (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
727 M_NOWAIT);
728 if ((*swd)->sw_ictx == NULL) {
729 swcr_freesession(NULL, i);
730 return ENOBUFS;
731 }
732
733 (*swd)->sw_octx = malloc(cri->cri_klen / 8,
734 M_CRYPTO_DATA, M_NOWAIT);
735 if ((*swd)->sw_octx == NULL) {
736 swcr_freesession(NULL, i);
737 return ENOBUFS;
738 }
739
740 /* Store the key so we can "append" it to the payload */
741 if (cri->cri_key != NULL) {
742 swcr_authprepare(axf, *swd, cri->cri_key,
743 cri->cri_klen);
744 }
745
746 (*swd)->sw_mlen = cri->cri_mlen;
747 (*swd)->sw_axf = axf;
748 break;
749 #ifdef notdef
750 case CRYPTO_MD5:
751 axf = &auth_hash_md5;
752 goto auth3common;
753
754 case CRYPTO_SHA1:
755 axf = &auth_hash_sha1;
756 auth3common:
757 (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
758 M_NOWAIT);
759 if ((*swd)->sw_ictx == NULL) {
760 swcr_freesession(NULL, i);
761 return ENOBUFS;
762 }
763
764 axf->Init((*swd)->sw_ictx);
765 (*swd)->sw_mlen = cri->cri_mlen;
766 (*swd)->sw_axf = axf;
767 break;
768 #endif
769 case CRYPTO_DEFLATE_COMP:
770 cxf = &comp_algo_deflate;
771 (*swd)->sw_cxf = cxf;
772 break;
773 default:
774 swcr_freesession(NULL, i);
775 return EINVAL;
776 }
777
778 (*swd)->sw_alg = cri->cri_alg;
779 cri = cri->cri_next;
780 swd = &((*swd)->sw_next);
781 }
782 return 0;
783 }
784
785 /*
786 * Free a session.
787 */
788 static int
789 swcr_freesession(void *arg, u_int64_t tid)
790 {
791 struct swcr_data *swd;
792 struct enc_xform *txf;
793 struct auth_hash *axf;
794 struct comp_algo *cxf;
795 u_int32_t sid = CRYPTO_SESID2LID(tid);
796
797 if (sid > swcr_sesnum || swcr_sessions == NULL ||
798 swcr_sessions[sid] == NULL)
799 return EINVAL;
800
801 /* Silently accept and return */
802 if (sid == 0)
803 return 0;
804
805 while ((swd = swcr_sessions[sid]) != NULL) {
806 swcr_sessions[sid] = swd->sw_next;
807
808 switch (swd->sw_alg) {
809 case CRYPTO_DES_CBC:
810 case CRYPTO_3DES_CBC:
811 case CRYPTO_BLF_CBC:
812 case CRYPTO_CAST_CBC:
813 case CRYPTO_SKIPJACK_CBC:
814 case CRYPTO_RIJNDAEL128_CBC:
815 case CRYPTO_NULL_CBC:
816 txf = swd->sw_exf;
817
818 if (swd->sw_kschedule)
819 txf->zerokey(&(swd->sw_kschedule));
820 break;
821
822 case CRYPTO_MD5_HMAC:
823 case CRYPTO_SHA1_HMAC:
824 case CRYPTO_SHA2_256_HMAC:
825 case CRYPTO_SHA2_384_HMAC:
826 case CRYPTO_SHA2_512_HMAC:
827 case CRYPTO_RIPEMD160_HMAC:
828 case CRYPTO_NULL_HMAC:
829 axf = swd->sw_axf;
830
831 if (swd->sw_ictx) {
832 bzero(swd->sw_ictx, axf->ctxsize);
833 free(swd->sw_ictx, M_CRYPTO_DATA);
834 }
835 if (swd->sw_octx) {
836 bzero(swd->sw_octx, axf->ctxsize);
837 free(swd->sw_octx, M_CRYPTO_DATA);
838 }
839 break;
840
841 case CRYPTO_MD5_KPDK:
842 case CRYPTO_SHA1_KPDK:
843 axf = swd->sw_axf;
844
845 if (swd->sw_ictx) {
846 bzero(swd->sw_ictx, axf->ctxsize);
847 free(swd->sw_ictx, M_CRYPTO_DATA);
848 }
849 if (swd->sw_octx) {
850 bzero(swd->sw_octx, swd->sw_klen);
851 free(swd->sw_octx, M_CRYPTO_DATA);
852 }
853 break;
854
855 case CRYPTO_MD5:
856 case CRYPTO_SHA1:
857 axf = swd->sw_axf;
858
859 if (swd->sw_ictx)
860 free(swd->sw_ictx, M_CRYPTO_DATA);
861 break;
862
863 case CRYPTO_DEFLATE_COMP:
864 cxf = swd->sw_cxf;
865 break;
866 }
867
868 FREE(swd, M_CRYPTO_DATA);
869 }
870 return 0;
871 }
872
873 /*
874 * Process a software request.
875 */
876 static int
877 swcr_process(void *arg, struct cryptop *crp, int hint)
878 {
879 struct cryptodesc *crd;
880 struct swcr_data *sw;
881 u_int32_t lid;
882
883 /* Sanity check */
884 if (crp == NULL)
885 return EINVAL;
886
887 if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
888 crp->crp_etype = EINVAL;
889 goto done;
890 }
891
892 lid = crp->crp_sid & 0xffffffff;
893 if (lid >= swcr_sesnum || lid == 0 || swcr_sessions[lid] == NULL) {
894 crp->crp_etype = ENOENT;
895 goto done;
896 }
897
898 /* Go through crypto descriptors, processing as we go */
899 for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
900 /*
901 * Find the crypto context.
902 *
903 * XXX Note that the logic here prevents us from having
904 * XXX the same algorithm multiple times in a session
905 * XXX (or rather, we can but it won't give us the right
906 * XXX results). To do that, we'd need some way of differentiating
907 * XXX between the various instances of an algorithm (so we can
908 * XXX locate the correct crypto context).
909 */
910 for (sw = swcr_sessions[lid];
911 sw && sw->sw_alg != crd->crd_alg;
912 sw = sw->sw_next)
913 ;
914
915 /* No such context ? */
916 if (sw == NULL) {
917 crp->crp_etype = EINVAL;
918 goto done;
919 }
920 switch (sw->sw_alg) {
921 case CRYPTO_DES_CBC:
922 case CRYPTO_3DES_CBC:
923 case CRYPTO_BLF_CBC:
924 case CRYPTO_CAST_CBC:
925 case CRYPTO_SKIPJACK_CBC:
926 case CRYPTO_RIJNDAEL128_CBC:
927 if ((crp->crp_etype = swcr_encdec(crd, sw,
928 crp->crp_buf, crp->crp_flags)) != 0)
929 goto done;
930 break;
931 case CRYPTO_NULL_CBC:
932 crp->crp_etype = 0;
933 break;
934 case CRYPTO_MD5_HMAC:
935 case CRYPTO_SHA1_HMAC:
936 case CRYPTO_SHA2_256_HMAC:
937 case CRYPTO_SHA2_384_HMAC:
938 case CRYPTO_SHA2_512_HMAC:
939 case CRYPTO_RIPEMD160_HMAC:
940 case CRYPTO_NULL_HMAC:
941 case CRYPTO_MD5_KPDK:
942 case CRYPTO_SHA1_KPDK:
943 case CRYPTO_MD5:
944 case CRYPTO_SHA1:
945 if ((crp->crp_etype = swcr_authcompute(crd, sw,
946 crp->crp_buf, crp->crp_flags)) != 0)
947 goto done;
948 break;
949
950 case CRYPTO_DEFLATE_COMP:
951 if ((crp->crp_etype = swcr_compdec(crd, sw,
952 crp->crp_buf, crp->crp_flags)) != 0)
953 goto done;
954 else
955 crp->crp_olen = (int)sw->sw_size;
956 break;
957
958 default:
959 /* Unknown/unsupported algorithm */
960 crp->crp_etype = EINVAL;
961 goto done;
962 }
963 }
964
965 done:
966 crypto_done(crp);
967 return 0;
968 }
969
970 /*
971 * Initialize the driver, called from the kernel main().
972 */
973 static void
974 swcr_init(void)
975 {
976 u_int i;
977
978 hmac_ipad_buffer = malloc(HMAC_MAX_BLOCK_LEN, M_CRYPTO_DATA, M_WAITOK);
979 for (i = 0; i < HMAC_MAX_BLOCK_LEN; i++)
980 hmac_ipad_buffer[i] = HMAC_IPAD_VAL;
981 hmac_opad_buffer = malloc(HMAC_MAX_BLOCK_LEN, M_CRYPTO_DATA, M_WAITOK);
982 for (i = 0; i < HMAC_MAX_BLOCK_LEN; i++)
983 hmac_opad_buffer[i] = HMAC_OPAD_VAL;
984
985 swcr_id = crypto_get_driverid(CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC);
986 if (swcr_id < 0)
987 panic("Software crypto device cannot initialize!");
988 crypto_register(swcr_id, CRYPTO_DES_CBC,
989 0, 0, swcr_newsession, swcr_freesession, swcr_process, NULL);
990 #define REGISTER(alg) \
991 crypto_register(swcr_id, alg, 0,0,NULL,NULL,NULL,NULL)
992 REGISTER(CRYPTO_3DES_CBC);
993 REGISTER(CRYPTO_BLF_CBC);
994 REGISTER(CRYPTO_CAST_CBC);
995 REGISTER(CRYPTO_SKIPJACK_CBC);
996 REGISTER(CRYPTO_NULL_CBC);
997 REGISTER(CRYPTO_MD5_HMAC);
998 REGISTER(CRYPTO_SHA1_HMAC);
999 REGISTER(CRYPTO_SHA2_256_HMAC);
1000 REGISTER(CRYPTO_SHA2_384_HMAC);
1001 REGISTER(CRYPTO_SHA2_512_HMAC);
1002 REGISTER(CRYPTO_RIPEMD160_HMAC);
1003 REGISTER(CRYPTO_NULL_HMAC);
1004 REGISTER(CRYPTO_MD5_KPDK);
1005 REGISTER(CRYPTO_SHA1_KPDK);
1006 REGISTER(CRYPTO_MD5);
1007 REGISTER(CRYPTO_SHA1);
1008 REGISTER(CRYPTO_RIJNDAEL128_CBC);
1009 REGISTER(CRYPTO_DEFLATE_COMP);
1010 #undef REGISTER
1011 }
1012 SYSINIT(cryptosoft_init, SI_SUB_PSEUDO, SI_ORDER_ANY, swcr_init, NULL)
1013
1014 static void
1015 swcr_uninit(void)
1016 {
1017
1018 if (swcr_sessions != NULL)
1019 FREE(swcr_sessions, M_CRYPTO_DATA);
1020 free(hmac_ipad_buffer, M_CRYPTO_DATA);
1021 free(hmac_opad_buffer, M_CRYPTO_DATA);
1022 }
1023 SYSUNINIT(cryptosoft_uninit, SI_SUB_PSEUDO, SI_ORDER_ANY, swcr_uninit, NULL);
Cache object: ff1ab79d05c536586d7c743aa5b8285f
|