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/5.2/sys/opencrypto/cryptosoft.c 116924 2003-06-27 20:07:10Z sam $");
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/cast128/cast128.h>
39 #include <crypto/sha1.h>
40 #include <opencrypto/rmd160.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[64] = {
49 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
50 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
51 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
52 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
53 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
54 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
55 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
56 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
57 };
58
59 u_int8_t hmac_opad_buffer[64] = {
60 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
61 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
62 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
63 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
64 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
65 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
66 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
67 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C
68 };
69
70
71 struct swcr_data **swcr_sessions = NULL;
72 u_int32_t swcr_sesnum = 0;
73 int32_t swcr_id = -1;
74
75 #define COPYBACK(x, a, b, c, d) \
76 (x) == CRYPTO_BUF_MBUF ? m_copyback((struct mbuf *)a,b,c,d) \
77 : cuio_copyback((struct uio *)a,b,c,d)
78 #define COPYDATA(x, a, b, c, d) \
79 (x) == CRYPTO_BUF_MBUF ? m_copydata((struct mbuf *)a,b,c,d) \
80 : cuio_copydata((struct uio *)a,b,c,d)
81
82 static int swcr_encdec(struct cryptodesc *, struct swcr_data *, caddr_t, int);
83 static int swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
84 struct swcr_data *sw, caddr_t buf, int outtype);
85 static int swcr_compdec(struct cryptodesc *, struct swcr_data *, caddr_t, int);
86 static int swcr_process(void *, struct cryptop *, int);
87 static int swcr_newsession(void *, u_int32_t *, struct cryptoini *);
88 static int swcr_freesession(void *, u_int64_t);
89
90 /*
91 * NB: These came over from openbsd and are kept private
92 * to the crypto code for now.
93 */
94 extern int m_apply(struct mbuf *m, int off, int len,
95 int (*f)(caddr_t, caddr_t, unsigned int), caddr_t fstate);
96
97 /*
98 * Apply a symmetric encryption/decryption algorithm.
99 */
100 static int
101 swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
102 int outtype)
103 {
104 unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN], *idat;
105 unsigned char *ivp, piv[EALG_MAX_BLOCK_LEN];
106 struct enc_xform *exf;
107 int i, k, j, blks;
108
109 exf = sw->sw_exf;
110 blks = exf->blocksize;
111
112 /* Check for non-padded data */
113 if (crd->crd_len % blks)
114 return EINVAL;
115
116 /* Initialize the IV */
117 if (crd->crd_flags & CRD_F_ENCRYPT) {
118 /* IV explicitly provided ? */
119 if (crd->crd_flags & CRD_F_IV_EXPLICIT)
120 bcopy(crd->crd_iv, iv, blks);
121 else {
122 /* Get random IV */
123 for (i = 0;
124 i + sizeof (u_int32_t) < EALG_MAX_BLOCK_LEN;
125 i += sizeof (u_int32_t)) {
126 u_int32_t temp = arc4random();
127
128 bcopy(&temp, iv + i, sizeof(u_int32_t));
129 }
130 /*
131 * What if the block size is not a multiple
132 * of sizeof (u_int32_t), which is the size of
133 * what arc4random() returns ?
134 */
135 if (EALG_MAX_BLOCK_LEN % sizeof (u_int32_t) != 0) {
136 u_int32_t temp = arc4random();
137
138 bcopy (&temp, iv + i,
139 EALG_MAX_BLOCK_LEN - i);
140 }
141 }
142
143 /* Do we need to write the IV */
144 if (!(crd->crd_flags & CRD_F_IV_PRESENT)) {
145 COPYBACK(outtype, buf, crd->crd_inject, blks, iv);
146 }
147
148 } else { /* Decryption */
149 /* IV explicitly provided ? */
150 if (crd->crd_flags & CRD_F_IV_EXPLICIT)
151 bcopy(crd->crd_iv, iv, blks);
152 else {
153 /* Get IV off buf */
154 COPYDATA(outtype, buf, crd->crd_inject, blks, iv);
155 }
156 }
157
158 ivp = iv;
159
160 if (outtype == CRYPTO_BUF_CONTIG) {
161 if (crd->crd_flags & CRD_F_ENCRYPT) {
162 for (i = crd->crd_skip;
163 i < crd->crd_skip + crd->crd_len; i += blks) {
164 /* XOR with the IV/previous block, as appropriate. */
165 if (i == crd->crd_skip)
166 for (k = 0; k < blks; k++)
167 buf[i + k] ^= ivp[k];
168 else
169 for (k = 0; k < blks; k++)
170 buf[i + k] ^= buf[i + k - blks];
171 exf->encrypt(sw->sw_kschedule, buf + i);
172 }
173 } else { /* Decrypt */
174 /*
175 * Start at the end, so we don't need to keep the encrypted
176 * block as the IV for the next block.
177 */
178 for (i = crd->crd_skip + crd->crd_len - blks;
179 i >= crd->crd_skip; i -= blks) {
180 exf->decrypt(sw->sw_kschedule, buf + i);
181
182 /* XOR with the IV/previous block, as appropriate */
183 if (i == crd->crd_skip)
184 for (k = 0; k < blks; k++)
185 buf[i + k] ^= ivp[k];
186 else
187 for (k = 0; k < blks; k++)
188 buf[i + k] ^= buf[i + k - blks];
189 }
190 }
191
192 return 0;
193 } else if (outtype == CRYPTO_BUF_MBUF) {
194 struct mbuf *m = (struct mbuf *) buf;
195
196 /* Find beginning of data */
197 m = m_getptr(m, crd->crd_skip, &k);
198 if (m == NULL)
199 return EINVAL;
200
201 i = crd->crd_len;
202
203 while (i > 0) {
204 /*
205 * If there's insufficient data at the end of
206 * an mbuf, we have to do some copying.
207 */
208 if (m->m_len < k + blks && m->m_len != k) {
209 m_copydata(m, k, blks, blk);
210
211 /* Actual encryption/decryption */
212 if (crd->crd_flags & CRD_F_ENCRYPT) {
213 /* XOR with previous block */
214 for (j = 0; j < blks; j++)
215 blk[j] ^= ivp[j];
216
217 exf->encrypt(sw->sw_kschedule, blk);
218
219 /*
220 * Keep encrypted block for XOR'ing
221 * with next block
222 */
223 bcopy(blk, iv, blks);
224 ivp = iv;
225 } else { /* decrypt */
226 /*
227 * Keep encrypted block for XOR'ing
228 * with next block
229 */
230 if (ivp == iv)
231 bcopy(blk, piv, blks);
232 else
233 bcopy(blk, iv, blks);
234
235 exf->decrypt(sw->sw_kschedule, blk);
236
237 /* XOR with previous block */
238 for (j = 0; j < blks; j++)
239 blk[j] ^= ivp[j];
240
241 if (ivp == iv)
242 bcopy(piv, iv, blks);
243 else
244 ivp = iv;
245 }
246
247 /* Copy back decrypted block */
248 m_copyback(m, k, blks, blk);
249
250 /* Advance pointer */
251 m = m_getptr(m, k + blks, &k);
252 if (m == NULL)
253 return EINVAL;
254
255 i -= blks;
256
257 /* Could be done... */
258 if (i == 0)
259 break;
260 }
261
262 /* Skip possibly empty mbufs */
263 if (k == m->m_len) {
264 for (m = m->m_next; m && m->m_len == 0;
265 m = m->m_next)
266 ;
267 k = 0;
268 }
269
270 /* Sanity check */
271 if (m == NULL)
272 return EINVAL;
273
274 /*
275 * Warning: idat may point to garbage here, but
276 * we only use it in the while() loop, only if
277 * there are indeed enough data.
278 */
279 idat = mtod(m, unsigned char *) + k;
280
281 while (m->m_len >= k + blks && i > 0) {
282 if (crd->crd_flags & CRD_F_ENCRYPT) {
283 /* XOR with previous block/IV */
284 for (j = 0; j < blks; j++)
285 idat[j] ^= ivp[j];
286
287 exf->encrypt(sw->sw_kschedule, idat);
288 ivp = idat;
289 } else { /* decrypt */
290 /*
291 * Keep encrypted block to be used
292 * in next block's processing.
293 */
294 if (ivp == iv)
295 bcopy(idat, piv, blks);
296 else
297 bcopy(idat, iv, blks);
298
299 exf->decrypt(sw->sw_kschedule, idat);
300
301 /* XOR with previous block/IV */
302 for (j = 0; j < blks; j++)
303 idat[j] ^= ivp[j];
304
305 if (ivp == iv)
306 bcopy(piv, iv, blks);
307 else
308 ivp = iv;
309 }
310
311 idat += blks;
312 k += blks;
313 i -= blks;
314 }
315 }
316
317 return 0; /* Done with mbuf encryption/decryption */
318 } else if (outtype == CRYPTO_BUF_IOV) {
319 struct uio *uio = (struct uio *) buf;
320 struct iovec *iov;
321
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 }
433
434 /* Unreachable */
435 return EINVAL;
436 }
437
438 /*
439 * Compute keyed-hash authenticator.
440 */
441 static int
442 swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
443 struct swcr_data *sw, caddr_t buf, int outtype)
444 {
445 unsigned char aalg[AALG_MAX_RESULT_LEN];
446 struct auth_hash *axf;
447 union authctx ctx;
448 int err;
449
450 if (sw->sw_ictx == 0)
451 return EINVAL;
452
453 axf = sw->sw_axf;
454
455 bcopy(sw->sw_ictx, &ctx, axf->ctxsize);
456
457 switch (outtype) {
458 case CRYPTO_BUF_CONTIG:
459 axf->Update(&ctx, buf + crd->crd_skip, crd->crd_len);
460 break;
461 case CRYPTO_BUF_MBUF:
462 err = m_apply((struct mbuf *) buf, crd->crd_skip, crd->crd_len,
463 (int (*)(caddr_t, caddr_t, unsigned int)) axf->Update,
464 (caddr_t) &ctx);
465 if (err)
466 return err;
467 break;
468 case CRYPTO_BUF_IOV:
469 default:
470 return EINVAL;
471 }
472
473 switch (sw->sw_alg) {
474 case CRYPTO_MD5_HMAC:
475 case CRYPTO_SHA1_HMAC:
476 case CRYPTO_SHA2_HMAC:
477 case CRYPTO_RIPEMD160_HMAC:
478 if (sw->sw_octx == NULL)
479 return EINVAL;
480
481 axf->Final(aalg, &ctx);
482 bcopy(sw->sw_octx, &ctx, axf->ctxsize);
483 axf->Update(&ctx, aalg, axf->hashsize);
484 axf->Final(aalg, &ctx);
485 break;
486
487 case CRYPTO_MD5_KPDK:
488 case CRYPTO_SHA1_KPDK:
489 if (sw->sw_octx == NULL)
490 return EINVAL;
491
492 axf->Update(&ctx, sw->sw_octx, sw->sw_klen);
493 axf->Final(aalg, &ctx);
494 break;
495
496 case CRYPTO_NULL_HMAC:
497 axf->Final(aalg, &ctx);
498 break;
499 }
500
501 /* Inject the authentication data */
502 if (outtype == CRYPTO_BUF_CONTIG)
503 bcopy(aalg, buf + crd->crd_inject, axf->authsize);
504 else
505 m_copyback((struct mbuf *) buf, crd->crd_inject,
506 axf->authsize, aalg);
507 return 0;
508 }
509
510 /*
511 * Apply a compression/decompression algorithm
512 */
513 static int
514 swcr_compdec(struct cryptodesc *crd, struct swcr_data *sw,
515 caddr_t buf, int outtype)
516 {
517 u_int8_t *data, *out;
518 struct comp_algo *cxf;
519 int adj;
520 u_int32_t result;
521
522 cxf = sw->sw_cxf;
523
524 /* We must handle the whole buffer of data in one time
525 * then if there is not all the data in the mbuf, we must
526 * copy in a buffer.
527 */
528
529 MALLOC(data, u_int8_t *, crd->crd_len, M_CRYPTO_DATA, M_NOWAIT);
530 if (data == NULL)
531 return (EINVAL);
532 COPYDATA(outtype, buf, crd->crd_skip, crd->crd_len, data);
533
534 if (crd->crd_flags & CRD_F_COMP)
535 result = cxf->compress(data, crd->crd_len, &out);
536 else
537 result = cxf->decompress(data, crd->crd_len, &out);
538
539 FREE(data, M_CRYPTO_DATA);
540 if (result == 0)
541 return EINVAL;
542
543 /* Copy back the (de)compressed data. m_copyback is
544 * extending the mbuf as necessary.
545 */
546 sw->sw_size = result;
547 /* Check the compressed size when doing compression */
548 if (crd->crd_flags & CRD_F_COMP) {
549 if (result > crd->crd_len) {
550 /* Compression was useless, we lost time */
551 FREE(out, M_CRYPTO_DATA);
552 return 0;
553 }
554 }
555
556 COPYBACK(outtype, buf, crd->crd_skip, result, out);
557 if (result < crd->crd_len) {
558 adj = result - crd->crd_len;
559 if (outtype == CRYPTO_BUF_MBUF) {
560 adj = result - crd->crd_len;
561 m_adj((struct mbuf *)buf, adj);
562 } else {
563 struct uio *uio = (struct uio *)buf;
564 int ind;
565
566 adj = crd->crd_len - result;
567 ind = uio->uio_iovcnt - 1;
568
569 while (adj > 0 && ind >= 0) {
570 if (adj < uio->uio_iov[ind].iov_len) {
571 uio->uio_iov[ind].iov_len -= adj;
572 break;
573 }
574
575 adj -= uio->uio_iov[ind].iov_len;
576 uio->uio_iov[ind].iov_len = 0;
577 ind--;
578 uio->uio_iovcnt--;
579 }
580 }
581 }
582 FREE(out, M_CRYPTO_DATA);
583 return 0;
584 }
585
586 /*
587 * Generate a new software session.
588 */
589 static int
590 swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
591 {
592 struct swcr_data **swd;
593 struct auth_hash *axf;
594 struct enc_xform *txf;
595 struct comp_algo *cxf;
596 u_int32_t i;
597 int k, error;
598
599 if (sid == NULL || cri == NULL)
600 return EINVAL;
601
602 if (swcr_sessions) {
603 for (i = 1; i < swcr_sesnum; i++)
604 if (swcr_sessions[i] == NULL)
605 break;
606 } else
607 i = 1; /* NB: to silence compiler warning */
608
609 if (swcr_sessions == NULL || i == swcr_sesnum) {
610 if (swcr_sessions == NULL) {
611 i = 1; /* We leave swcr_sessions[0] empty */
612 swcr_sesnum = CRYPTO_SW_SESSIONS;
613 } else
614 swcr_sesnum *= 2;
615
616 swd = malloc(swcr_sesnum * sizeof(struct swcr_data *),
617 M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
618 if (swd == NULL) {
619 /* Reset session number */
620 if (swcr_sesnum == CRYPTO_SW_SESSIONS)
621 swcr_sesnum = 0;
622 else
623 swcr_sesnum /= 2;
624 return ENOBUFS;
625 }
626
627 /* Copy existing sessions */
628 if (swcr_sessions) {
629 bcopy(swcr_sessions, swd,
630 (swcr_sesnum / 2) * sizeof(struct swcr_data *));
631 free(swcr_sessions, M_CRYPTO_DATA);
632 }
633
634 swcr_sessions = swd;
635 }
636
637 swd = &swcr_sessions[i];
638 *sid = i;
639
640 while (cri) {
641 MALLOC(*swd, struct swcr_data *, sizeof(struct swcr_data),
642 M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
643 if (*swd == NULL) {
644 swcr_freesession(NULL, i);
645 return ENOBUFS;
646 }
647
648 switch (cri->cri_alg) {
649 case CRYPTO_DES_CBC:
650 txf = &enc_xform_des;
651 goto enccommon;
652 case CRYPTO_3DES_CBC:
653 txf = &enc_xform_3des;
654 goto enccommon;
655 case CRYPTO_BLF_CBC:
656 txf = &enc_xform_blf;
657 goto enccommon;
658 case CRYPTO_CAST_CBC:
659 txf = &enc_xform_cast5;
660 goto enccommon;
661 case CRYPTO_SKIPJACK_CBC:
662 txf = &enc_xform_skipjack;
663 goto enccommon;
664 case CRYPTO_RIJNDAEL128_CBC:
665 txf = &enc_xform_rijndael128;
666 goto enccommon;
667 case CRYPTO_NULL_CBC:
668 txf = &enc_xform_null;
669 goto enccommon;
670 enccommon:
671 error = txf->setkey(&((*swd)->sw_kschedule),
672 cri->cri_key, cri->cri_klen / 8);
673 if (error) {
674 swcr_freesession(NULL, i);
675 return error;
676 }
677 (*swd)->sw_exf = txf;
678 break;
679
680 case CRYPTO_MD5_HMAC:
681 axf = &auth_hash_hmac_md5_96;
682 goto authcommon;
683 case CRYPTO_SHA1_HMAC:
684 axf = &auth_hash_hmac_sha1_96;
685 goto authcommon;
686 case CRYPTO_SHA2_HMAC:
687 if (cri->cri_klen == 256)
688 axf = &auth_hash_hmac_sha2_256;
689 else if (cri->cri_klen == 384)
690 axf = &auth_hash_hmac_sha2_384;
691 else if (cri->cri_klen == 512)
692 axf = &auth_hash_hmac_sha2_512;
693 else {
694 swcr_freesession(NULL, i);
695 return EINVAL;
696 }
697 goto authcommon;
698 case CRYPTO_NULL_HMAC:
699 axf = &auth_hash_null;
700 goto authcommon;
701 case CRYPTO_RIPEMD160_HMAC:
702 axf = &auth_hash_hmac_ripemd_160_96;
703 authcommon:
704 (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
705 M_NOWAIT);
706 if ((*swd)->sw_ictx == NULL) {
707 swcr_freesession(NULL, i);
708 return ENOBUFS;
709 }
710
711 (*swd)->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA,
712 M_NOWAIT);
713 if ((*swd)->sw_octx == NULL) {
714 swcr_freesession(NULL, i);
715 return ENOBUFS;
716 }
717
718 for (k = 0; k < cri->cri_klen / 8; k++)
719 cri->cri_key[k] ^= HMAC_IPAD_VAL;
720
721 axf->Init((*swd)->sw_ictx);
722 axf->Update((*swd)->sw_ictx, cri->cri_key,
723 cri->cri_klen / 8);
724 axf->Update((*swd)->sw_ictx, hmac_ipad_buffer,
725 HMAC_BLOCK_LEN - (cri->cri_klen / 8));
726
727 for (k = 0; k < cri->cri_klen / 8; k++)
728 cri->cri_key[k] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
729
730 axf->Init((*swd)->sw_octx);
731 axf->Update((*swd)->sw_octx, cri->cri_key,
732 cri->cri_klen / 8);
733 axf->Update((*swd)->sw_octx, hmac_opad_buffer,
734 HMAC_BLOCK_LEN - (cri->cri_klen / 8));
735
736 for (k = 0; k < cri->cri_klen / 8; k++)
737 cri->cri_key[k] ^= HMAC_OPAD_VAL;
738 (*swd)->sw_axf = axf;
739 break;
740
741 case CRYPTO_MD5_KPDK:
742 axf = &auth_hash_key_md5;
743 goto auth2common;
744
745 case CRYPTO_SHA1_KPDK:
746 axf = &auth_hash_key_sha1;
747 auth2common:
748 (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
749 M_NOWAIT);
750 if ((*swd)->sw_ictx == NULL) {
751 swcr_freesession(NULL, i);
752 return ENOBUFS;
753 }
754
755 /* Store the key so we can "append" it to the payload */
756 (*swd)->sw_octx = malloc(cri->cri_klen / 8, M_CRYPTO_DATA,
757 M_NOWAIT);
758 if ((*swd)->sw_octx == NULL) {
759 swcr_freesession(NULL, i);
760 return ENOBUFS;
761 }
762
763 (*swd)->sw_klen = cri->cri_klen / 8;
764 bcopy(cri->cri_key, (*swd)->sw_octx, cri->cri_klen / 8);
765 axf->Init((*swd)->sw_ictx);
766 axf->Update((*swd)->sw_ictx, cri->cri_key,
767 cri->cri_klen / 8);
768 axf->Final(NULL, (*swd)->sw_ictx);
769 (*swd)->sw_axf = axf;
770 break;
771 #ifdef notdef
772 case CRYPTO_MD5:
773 axf = &auth_hash_md5;
774 goto auth3common;
775
776 case CRYPTO_SHA1:
777 axf = &auth_hash_sha1;
778 auth3common:
779 (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
780 M_NOWAIT);
781 if ((*swd)->sw_ictx == NULL) {
782 swcr_freesession(NULL, i);
783 return ENOBUFS;
784 }
785
786 axf->Init((*swd)->sw_ictx);
787 (*swd)->sw_axf = axf;
788 break;
789 #endif
790 case CRYPTO_DEFLATE_COMP:
791 cxf = &comp_algo_deflate;
792 (*swd)->sw_cxf = cxf;
793 break;
794 default:
795 swcr_freesession(NULL, i);
796 return EINVAL;
797 }
798
799 (*swd)->sw_alg = cri->cri_alg;
800 cri = cri->cri_next;
801 swd = &((*swd)->sw_next);
802 }
803 return 0;
804 }
805
806 /*
807 * Free a session.
808 */
809 static int
810 swcr_freesession(void *arg, u_int64_t tid)
811 {
812 struct swcr_data *swd;
813 struct enc_xform *txf;
814 struct auth_hash *axf;
815 struct comp_algo *cxf;
816 u_int32_t sid = CRYPTO_SESID2LID(tid);
817
818 if (sid > swcr_sesnum || swcr_sessions == NULL ||
819 swcr_sessions[sid] == NULL)
820 return EINVAL;
821
822 /* Silently accept and return */
823 if (sid == 0)
824 return 0;
825
826 while ((swd = swcr_sessions[sid]) != NULL) {
827 swcr_sessions[sid] = swd->sw_next;
828
829 switch (swd->sw_alg) {
830 case CRYPTO_DES_CBC:
831 case CRYPTO_3DES_CBC:
832 case CRYPTO_BLF_CBC:
833 case CRYPTO_CAST_CBC:
834 case CRYPTO_SKIPJACK_CBC:
835 case CRYPTO_RIJNDAEL128_CBC:
836 case CRYPTO_NULL_CBC:
837 txf = swd->sw_exf;
838
839 if (swd->sw_kschedule)
840 txf->zerokey(&(swd->sw_kschedule));
841 break;
842
843 case CRYPTO_MD5_HMAC:
844 case CRYPTO_SHA1_HMAC:
845 case CRYPTO_SHA2_HMAC:
846 case CRYPTO_RIPEMD160_HMAC:
847 case CRYPTO_NULL_HMAC:
848 axf = swd->sw_axf;
849
850 if (swd->sw_ictx) {
851 bzero(swd->sw_ictx, axf->ctxsize);
852 free(swd->sw_ictx, M_CRYPTO_DATA);
853 }
854 if (swd->sw_octx) {
855 bzero(swd->sw_octx, axf->ctxsize);
856 free(swd->sw_octx, M_CRYPTO_DATA);
857 }
858 break;
859
860 case CRYPTO_MD5_KPDK:
861 case CRYPTO_SHA1_KPDK:
862 axf = swd->sw_axf;
863
864 if (swd->sw_ictx) {
865 bzero(swd->sw_ictx, axf->ctxsize);
866 free(swd->sw_ictx, M_CRYPTO_DATA);
867 }
868 if (swd->sw_octx) {
869 bzero(swd->sw_octx, swd->sw_klen);
870 free(swd->sw_octx, M_CRYPTO_DATA);
871 }
872 break;
873
874 case CRYPTO_MD5:
875 case CRYPTO_SHA1:
876 axf = swd->sw_axf;
877
878 if (swd->sw_ictx)
879 free(swd->sw_ictx, M_CRYPTO_DATA);
880 break;
881
882 case CRYPTO_DEFLATE_COMP:
883 cxf = swd->sw_cxf;
884 break;
885 }
886
887 FREE(swd, M_CRYPTO_DATA);
888 }
889 return 0;
890 }
891
892 /*
893 * Process a software request.
894 */
895 static int
896 swcr_process(void *arg, struct cryptop *crp, int hint)
897 {
898 struct cryptodesc *crd;
899 struct swcr_data *sw;
900 u_int32_t lid;
901 int type;
902
903 /* Sanity check */
904 if (crp == NULL)
905 return EINVAL;
906
907 if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
908 crp->crp_etype = EINVAL;
909 goto done;
910 }
911
912 lid = crp->crp_sid & 0xffffffff;
913 if (lid >= swcr_sesnum || lid == 0 || swcr_sessions[lid] == NULL) {
914 crp->crp_etype = ENOENT;
915 goto done;
916 }
917
918 if (crp->crp_flags & CRYPTO_F_IMBUF) {
919 type = CRYPTO_BUF_MBUF;
920 } else if (crp->crp_flags & CRYPTO_F_IOV) {
921 type = CRYPTO_BUF_IOV;
922 } else {
923 type = CRYPTO_BUF_CONTIG;
924 }
925
926 /* Go through crypto descriptors, processing as we go */
927 for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
928 /*
929 * Find the crypto context.
930 *
931 * XXX Note that the logic here prevents us from having
932 * XXX the same algorithm multiple times in a session
933 * XXX (or rather, we can but it won't give us the right
934 * XXX results). To do that, we'd need some way of differentiating
935 * XXX between the various instances of an algorithm (so we can
936 * XXX locate the correct crypto context).
937 */
938 for (sw = swcr_sessions[lid];
939 sw && sw->sw_alg != crd->crd_alg;
940 sw = sw->sw_next)
941 ;
942
943 /* No such context ? */
944 if (sw == NULL) {
945 crp->crp_etype = EINVAL;
946 goto done;
947 }
948 switch (sw->sw_alg) {
949 case CRYPTO_DES_CBC:
950 case CRYPTO_3DES_CBC:
951 case CRYPTO_BLF_CBC:
952 case CRYPTO_CAST_CBC:
953 case CRYPTO_SKIPJACK_CBC:
954 case CRYPTO_RIJNDAEL128_CBC:
955 if ((crp->crp_etype = swcr_encdec(crd, sw,
956 crp->crp_buf, type)) != 0)
957 goto done;
958 break;
959 case CRYPTO_NULL_CBC:
960 crp->crp_etype = 0;
961 break;
962 case CRYPTO_MD5_HMAC:
963 case CRYPTO_SHA1_HMAC:
964 case CRYPTO_SHA2_HMAC:
965 case CRYPTO_RIPEMD160_HMAC:
966 case CRYPTO_NULL_HMAC:
967 case CRYPTO_MD5_KPDK:
968 case CRYPTO_SHA1_KPDK:
969 case CRYPTO_MD5:
970 case CRYPTO_SHA1:
971 if ((crp->crp_etype = swcr_authcompute(crp, crd, sw,
972 crp->crp_buf, type)) != 0)
973 goto done;
974 break;
975
976 case CRYPTO_DEFLATE_COMP:
977 if ((crp->crp_etype = swcr_compdec(crd, sw,
978 crp->crp_buf, type)) != 0)
979 goto done;
980 else
981 crp->crp_olen = (int)sw->sw_size;
982 break;
983
984 default:
985 /* Unknown/unsupported algorithm */
986 crp->crp_etype = EINVAL;
987 goto done;
988 }
989 }
990
991 done:
992 crypto_done(crp);
993 return 0;
994 }
995
996 /*
997 * Initialize the driver, called from the kernel main().
998 */
999 static void
1000 swcr_init(void)
1001 {
1002 swcr_id = crypto_get_driverid(CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC);
1003 if (swcr_id < 0)
1004 panic("Software crypto device cannot initialize!");
1005 crypto_register(swcr_id, CRYPTO_DES_CBC,
1006 0, 0, swcr_newsession, swcr_freesession, swcr_process, NULL);
1007 #define REGISTER(alg) \
1008 crypto_register(swcr_id, alg, 0,0,NULL,NULL,NULL,NULL)
1009 REGISTER(CRYPTO_3DES_CBC);
1010 REGISTER(CRYPTO_BLF_CBC);
1011 REGISTER(CRYPTO_CAST_CBC);
1012 REGISTER(CRYPTO_SKIPJACK_CBC);
1013 REGISTER(CRYPTO_NULL_CBC);
1014 REGISTER(CRYPTO_MD5_HMAC);
1015 REGISTER(CRYPTO_SHA1_HMAC);
1016 REGISTER(CRYPTO_SHA2_HMAC);
1017 REGISTER(CRYPTO_RIPEMD160_HMAC);
1018 REGISTER(CRYPTO_NULL_HMAC);
1019 REGISTER(CRYPTO_MD5_KPDK);
1020 REGISTER(CRYPTO_SHA1_KPDK);
1021 REGISTER(CRYPTO_MD5);
1022 REGISTER(CRYPTO_SHA1);
1023 REGISTER(CRYPTO_RIJNDAEL128_CBC);
1024 REGISTER(CRYPTO_DEFLATE_COMP);
1025 #undef REGISTER
1026 }
1027 SYSINIT(cryptosoft_init, SI_SUB_PSEUDO, SI_ORDER_ANY, swcr_init, NULL)
Cache object: 3abeb53cd59f8be44775b079dc1216b3
|