Annotation of sys/crypto/cryptosoft.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: cryptosoft.c,v 1.46 2006/12/29 13:04:37 pedro 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/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: * Apply a symmetric encryption/decryption algorithm.
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: /* Check for non-padded data */
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: /* 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, ivlen);
107: else
108: arc4random_bytes(iv, ivlen);
109:
110: /* Do we need to write the IV */
111: if (!(crd->crd_flags & CRD_F_IV_PRESENT)) {
112: COPYBACK(outtype, buf, crd->crd_inject, ivlen, iv);
113: }
114:
115: } else { /* Decryption */
116: /* IV explicitly provided ? */
117: if (crd->crd_flags & CRD_F_IV_EXPLICIT)
118: bcopy(crd->crd_iv, iv, ivlen);
119: else {
120: /* Get IV off buf */
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: /* Find beginning of data */
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: * If there's insufficient data at the end of
141: * an mbuf, we have to do some copying.
142: */
143: if (m->m_len < k + blks && m->m_len != k) {
144: m_copydata(m, k, blks, blk);
145:
146: /* Actual encryption/decryption */
147: if (exf->reinit) {
148: exf->encrypt(sw->sw_kschedule, blk);
149: } else if (crd->crd_flags & CRD_F_ENCRYPT) {
150: /* XOR with previous block */
151: for (j = 0; j < blks; j++)
152: blk[j] ^= ivp[j];
153:
154: exf->encrypt(sw->sw_kschedule, blk);
155:
156: /*
157: * Keep encrypted block for XOR'ing
158: * with next block
159: */
160: bcopy(blk, iv, blks);
161: ivp = iv;
162: } else { /* decrypt */
163: /*
164: * Keep encrypted block for XOR'ing
165: * with next block
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: /* XOR with previous block */
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: /* Copy back decrypted block */
185: m_copyback(m, k, blks, blk);
186:
187: /* Advance pointer */
188: m = m_getptr(m, k + blks, &k);
189: if (m == NULL)
190: return EINVAL;
191:
192: i -= blks;
193:
194: /* Could be done... */
195: if (i == 0)
196: break;
197: }
198:
199: /* Skip possibly empty mbufs */
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: /* Sanity check */
208: if (m == NULL)
209: return EINVAL;
210:
211: /*
212: * Warning: idat may point to garbage here, but
213: * we only use it in the while() loop, only if
214: * there are indeed enough data.
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: /* XOR with previous block/IV */
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 { /* decrypt */
229: /*
230: * Keep encrypted block to be used
231: * in next block's processing.
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: /* XOR with previous block/IV */
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: /* Find beginning of data */
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: * If there's insufficient data at the end,
267: * we have to do some copying.
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: /* Actual encryption/decryption */
274: if (exf->reinit) {
275: exf->encrypt(sw->sw_kschedule, blk);
276: } else if (crd->crd_flags & CRD_F_ENCRYPT) {
277: /* XOR with previous block */
278: for (j = 0; j < blks; j++)
279: blk[j] ^= ivp[j];
280:
281: exf->encrypt(sw->sw_kschedule, blk);
282:
283: /*
284: * Keep encrypted block for XOR'ing
285: * with next block
286: */
287: bcopy(blk, iv, blks);
288: ivp = iv;
289: } else { /* decrypt */
290: /*
291: * Keep encrypted block for XOR'ing
292: * with next block
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: /* XOR with previous block */
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: /* Copy back decrypted block */
312: cuio_copyback(uio, k, blks, blk);
313:
314: count += blks;
315:
316: /* Advance pointer */
317: ind = cuio_getptr(uio, count, &k);
318: if (ind == -1)
319: return (EINVAL);
320:
321: i -= blks;
322:
323: /* Could be done... */
324: if (i == 0)
325: break;
326: }
327:
328: /*
329: * Warning: idat may point to garbage here, but
330: * we only use it in the while() loop, only if
331: * there are indeed enough data.
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: /* XOR with previous block/IV */
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 { /* decrypt */
347: /*
348: * Keep encrypted block to be used
349: * in next block's processing.
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: /* XOR with previous block/IV */
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; /* Done with encryption/decryption */
377: }
378:
379: /*
380: * Compute keyed-hash authenticator.
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: /* Inject the authentication data */
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: * Apply a compression/decompression algorithm
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: /* We must handle the whole buffer of data in one time
466: * then if there is not all the data in the mbuf, we must
467: * copy in a buffer.
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: /* Copy back the (de)compressed data. m_copyback is
485: * extending the mbuf as necessary.
486: */
487: sw->sw_size = result;
488: /* Check the compressed size when doing compression */
489: if (crd->crd_flags & CRD_F_COMP) {
490: if (result > crd->crd_len) {
491: /* Compression was useless, we lost time */
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: * Generate a new software session.
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; /* We leave swcr_sessions[0] empty */
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: /* Reset session number */
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: /* Copy existing sessions */
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: /* Store the key so we can "append" it to the payload */
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: * Free a session.
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: /* Silently accept and return */
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: * Process a software request.
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: /* Sanity check */
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: /* Go through crypto descriptors, processing as we go */
860: for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
861: /*
862: * Find the crypto context.
863: *
864: * XXX Note that the logic here prevents us from having
865: * XXX the same algorithm multiple times in a session
866: * XXX (or rather, we can but it won't give us the right
867: * XXX results). To do that, we'd need some way of differentiating
868: * XXX between the various instances of an algorithm (so we can
869: * XXX locate the correct crypto context).
870: */
871: for (sw = swcr_sessions[lid];
872: sw && sw->sw_alg != crd->crd_alg;
873: sw = sw->sw_next)
874: ;
875:
876: /* No such context ? */
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: /* Unknown/unsupported algorithm */
921: crp->crp_etype = EINVAL;
922: goto done;
923: }
924: }
925:
926: done:
927: crypto_done(crp);
928: return 0;
929: }
930:
931: /*
932: * Initialize the driver, called from the kernel main().
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: /* This should never happen */
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: }
CVSweb