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