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