cryptosoft.c revision 1.2 1 1.2 jonathan /* $NetBSD: cryptosoft.c,v 1.2 2003/07/26 22:53:44 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.2 jonathan __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.2 2003/07/26 22:53:44 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.2 jonathan #ifdef __FreeBSD__
587 1.2 jonathan /*XXX FIXME: handle iov case*/
588 1.2 jonathan return EINVAL;
589 1.2 jonathan #else
590 1.2 jonathan err = cuio_apply((struct uio *) buf, crd->crd_skip,
591 1.2 jonathan crd->crd_len,
592 1.2 jonathan (int (*)(caddr_t, caddr_t, unsigned int)) axf->Update,
593 1.2 jonathan (caddr_t) &ctx);
594 1.2 jonathan if (err) {
595 1.2 jonathan return err;
596 1.2 jonathan }
597 1.2 jonathan #endif
598 1.2 jonathan break;
599 1.1 jonathan default:
600 1.1 jonathan return EINVAL;
601 1.1 jonathan }
602 1.1 jonathan
603 1.1 jonathan switch (sw->sw_alg) {
604 1.1 jonathan case CRYPTO_MD5_HMAC:
605 1.1 jonathan case CRYPTO_SHA1_HMAC:
606 1.1 jonathan case CRYPTO_SHA2_HMAC:
607 1.1 jonathan case CRYPTO_RIPEMD160_HMAC:
608 1.1 jonathan if (sw->sw_octx == NULL)
609 1.1 jonathan return EINVAL;
610 1.1 jonathan
611 1.1 jonathan axf->Final(aalg, &ctx);
612 1.1 jonathan bcopy(sw->sw_octx, &ctx, axf->ctxsize);
613 1.1 jonathan axf->Update(&ctx, aalg, axf->hashsize);
614 1.1 jonathan axf->Final(aalg, &ctx);
615 1.1 jonathan break;
616 1.1 jonathan
617 1.1 jonathan case CRYPTO_MD5_KPDK:
618 1.1 jonathan case CRYPTO_SHA1_KPDK:
619 1.1 jonathan if (sw->sw_octx == NULL)
620 1.1 jonathan return EINVAL;
621 1.1 jonathan
622 1.1 jonathan axf->Update(&ctx, sw->sw_octx, sw->sw_klen);
623 1.1 jonathan axf->Final(aalg, &ctx);
624 1.1 jonathan break;
625 1.1 jonathan
626 1.1 jonathan case CRYPTO_NULL_HMAC:
627 1.1 jonathan case CRYPTO_MD5:
628 1.1 jonathan case CRYPTO_SHA1:
629 1.1 jonathan axf->Final(aalg, &ctx);
630 1.1 jonathan break;
631 1.1 jonathan }
632 1.1 jonathan
633 1.1 jonathan /* Inject the authentication data */
634 1.2 jonathan switch (outtype) {
635 1.2 jonathan case CRYPTO_BUF_CONTIG:
636 1.1 jonathan bcopy(aalg, buf + crd->crd_inject, axf->authsize);
637 1.2 jonathan break;
638 1.2 jonathan case CRYPTO_BUF_MBUF:
639 1.1 jonathan m_copyback((struct mbuf *) buf, crd->crd_inject,
640 1.1 jonathan axf->authsize, aalg);
641 1.2 jonathan break;
642 1.2 jonathan case CRYPTO_BUF_IOV:
643 1.2 jonathan bcopy(aalg, crp->crp_mac, axf->authsize);
644 1.2 jonathan break;
645 1.2 jonathan default:
646 1.2 jonathan return EINVAL;
647 1.2 jonathan }
648 1.1 jonathan return 0;
649 1.1 jonathan }
650 1.1 jonathan
651 1.1 jonathan /*
652 1.1 jonathan * Apply a compression/decompression algorithm
653 1.1 jonathan */
654 1.1 jonathan static int
655 1.1 jonathan swcr_compdec(struct cryptodesc *crd, struct swcr_data *sw,
656 1.1 jonathan caddr_t buf, int outtype)
657 1.1 jonathan {
658 1.1 jonathan u_int8_t *data, *out;
659 1.1 jonathan struct comp_algo *cxf;
660 1.1 jonathan int adj;
661 1.1 jonathan u_int32_t result;
662 1.1 jonathan
663 1.1 jonathan cxf = sw->sw_cxf;
664 1.1 jonathan
665 1.1 jonathan /* We must handle the whole buffer of data in one time
666 1.1 jonathan * then if there is not all the data in the mbuf, we must
667 1.1 jonathan * copy in a buffer.
668 1.1 jonathan */
669 1.1 jonathan
670 1.1 jonathan MALLOC(data, u_int8_t *, crd->crd_len, M_CRYPTO_DATA, M_NOWAIT);
671 1.1 jonathan if (data == NULL)
672 1.1 jonathan return (EINVAL);
673 1.1 jonathan COPYDATA(outtype, buf, crd->crd_skip, crd->crd_len, data);
674 1.1 jonathan
675 1.1 jonathan if (crd->crd_flags & CRD_F_COMP)
676 1.1 jonathan result = cxf->compress(data, crd->crd_len, &out);
677 1.1 jonathan else
678 1.1 jonathan result = cxf->decompress(data, crd->crd_len, &out);
679 1.1 jonathan
680 1.1 jonathan FREE(data, M_CRYPTO_DATA);
681 1.1 jonathan if (result == 0)
682 1.1 jonathan return EINVAL;
683 1.1 jonathan
684 1.1 jonathan /* Copy back the (de)compressed data. m_copyback is
685 1.1 jonathan * extending the mbuf as necessary.
686 1.1 jonathan */
687 1.1 jonathan sw->sw_size = result;
688 1.1 jonathan /* Check the compressed size when doing compression */
689 1.1 jonathan if (crd->crd_flags & CRD_F_COMP) {
690 1.1 jonathan if (result > crd->crd_len) {
691 1.1 jonathan /* Compression was useless, we lost time */
692 1.1 jonathan FREE(out, M_CRYPTO_DATA);
693 1.1 jonathan return 0;
694 1.1 jonathan }
695 1.1 jonathan }
696 1.1 jonathan
697 1.1 jonathan COPYBACK(outtype, buf, crd->crd_skip, result, out);
698 1.1 jonathan if (result < crd->crd_len) {
699 1.1 jonathan adj = result - crd->crd_len;
700 1.1 jonathan if (outtype == CRYPTO_BUF_MBUF) {
701 1.1 jonathan adj = result - crd->crd_len;
702 1.1 jonathan m_adj((struct mbuf *)buf, adj);
703 1.1 jonathan } else {
704 1.1 jonathan struct uio *uio = (struct uio *)buf;
705 1.1 jonathan int ind;
706 1.1 jonathan
707 1.1 jonathan adj = crd->crd_len - result;
708 1.1 jonathan ind = uio->uio_iovcnt - 1;
709 1.1 jonathan
710 1.1 jonathan while (adj > 0 && ind >= 0) {
711 1.1 jonathan if (adj < uio->uio_iov[ind].iov_len) {
712 1.1 jonathan uio->uio_iov[ind].iov_len -= adj;
713 1.1 jonathan break;
714 1.1 jonathan }
715 1.1 jonathan
716 1.1 jonathan adj -= uio->uio_iov[ind].iov_len;
717 1.1 jonathan uio->uio_iov[ind].iov_len = 0;
718 1.1 jonathan ind--;
719 1.1 jonathan uio->uio_iovcnt--;
720 1.1 jonathan }
721 1.1 jonathan }
722 1.1 jonathan }
723 1.1 jonathan FREE(out, M_CRYPTO_DATA);
724 1.1 jonathan return 0;
725 1.1 jonathan }
726 1.1 jonathan
727 1.1 jonathan /*
728 1.1 jonathan * Generate a new software session.
729 1.1 jonathan */
730 1.1 jonathan static int
731 1.1 jonathan swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
732 1.1 jonathan {
733 1.1 jonathan struct swcr_data **swd;
734 1.1 jonathan struct auth_hash *axf;
735 1.1 jonathan struct enc_xform *txf;
736 1.1 jonathan struct comp_algo *cxf;
737 1.1 jonathan u_int32_t i;
738 1.1 jonathan int k, error;
739 1.1 jonathan
740 1.1 jonathan if (sid == NULL || cri == NULL)
741 1.1 jonathan return EINVAL;
742 1.1 jonathan
743 1.1 jonathan if (swcr_sessions) {
744 1.1 jonathan for (i = 1; i < swcr_sesnum; i++)
745 1.1 jonathan if (swcr_sessions[i] == NULL)
746 1.1 jonathan break;
747 1.1 jonathan } else
748 1.1 jonathan i = 1; /* NB: to silence compiler warning */
749 1.1 jonathan
750 1.1 jonathan if (swcr_sessions == NULL || i == swcr_sesnum) {
751 1.1 jonathan if (swcr_sessions == NULL) {
752 1.1 jonathan i = 1; /* We leave swcr_sessions[0] empty */
753 1.1 jonathan swcr_sesnum = CRYPTO_SW_SESSIONS;
754 1.1 jonathan } else
755 1.1 jonathan swcr_sesnum *= 2;
756 1.1 jonathan
757 1.1 jonathan swd = malloc(swcr_sesnum * sizeof(struct swcr_data *),
758 1.1 jonathan M_CRYPTO_DATA, M_NOWAIT);
759 1.1 jonathan if (swd == NULL) {
760 1.1 jonathan /* Reset session number */
761 1.1 jonathan if (swcr_sesnum == CRYPTO_SW_SESSIONS)
762 1.1 jonathan swcr_sesnum = 0;
763 1.1 jonathan else
764 1.1 jonathan swcr_sesnum /= 2;
765 1.1 jonathan return ENOBUFS;
766 1.1 jonathan }
767 1.1 jonathan
768 1.1 jonathan bzero(swd, swcr_sesnum * sizeof(struct swcr_data *));
769 1.1 jonathan
770 1.1 jonathan /* Copy existing sessions */
771 1.1 jonathan if (swcr_sessions) {
772 1.1 jonathan bcopy(swcr_sessions, swd,
773 1.1 jonathan (swcr_sesnum / 2) * sizeof(struct swcr_data *));
774 1.1 jonathan free(swcr_sessions, M_CRYPTO_DATA);
775 1.1 jonathan }
776 1.1 jonathan
777 1.1 jonathan swcr_sessions = swd;
778 1.1 jonathan }
779 1.1 jonathan
780 1.1 jonathan swd = &swcr_sessions[i];
781 1.1 jonathan *sid = i;
782 1.1 jonathan
783 1.1 jonathan while (cri) {
784 1.1 jonathan MALLOC(*swd, struct swcr_data *, sizeof(struct swcr_data),
785 1.1 jonathan M_CRYPTO_DATA, M_NOWAIT);
786 1.1 jonathan if (*swd == NULL) {
787 1.1 jonathan swcr_freesession(NULL, i);
788 1.1 jonathan return ENOBUFS;
789 1.1 jonathan }
790 1.1 jonathan bzero(*swd, sizeof(struct swcr_data));
791 1.1 jonathan
792 1.1 jonathan switch (cri->cri_alg) {
793 1.1 jonathan case CRYPTO_DES_CBC:
794 1.1 jonathan txf = &enc_xform_des;
795 1.1 jonathan goto enccommon;
796 1.1 jonathan case CRYPTO_3DES_CBC:
797 1.1 jonathan txf = &enc_xform_3des;
798 1.1 jonathan goto enccommon;
799 1.1 jonathan case CRYPTO_BLF_CBC:
800 1.1 jonathan txf = &enc_xform_blf;
801 1.1 jonathan goto enccommon;
802 1.1 jonathan case CRYPTO_CAST_CBC:
803 1.1 jonathan txf = &enc_xform_cast5;
804 1.1 jonathan goto enccommon;
805 1.1 jonathan case CRYPTO_SKIPJACK_CBC:
806 1.1 jonathan txf = &enc_xform_skipjack;
807 1.1 jonathan goto enccommon;
808 1.1 jonathan case CRYPTO_RIJNDAEL128_CBC:
809 1.1 jonathan txf = &enc_xform_rijndael128;
810 1.1 jonathan goto enccommon;
811 1.1 jonathan case CRYPTO_NULL_CBC:
812 1.1 jonathan txf = &enc_xform_null;
813 1.1 jonathan goto enccommon;
814 1.1 jonathan enccommon:
815 1.1 jonathan error = txf->setkey(&((*swd)->sw_kschedule),
816 1.1 jonathan cri->cri_key, cri->cri_klen / 8);
817 1.1 jonathan if (error) {
818 1.1 jonathan swcr_freesession(NULL, i);
819 1.1 jonathan return error;
820 1.1 jonathan }
821 1.1 jonathan (*swd)->sw_exf = txf;
822 1.1 jonathan break;
823 1.1 jonathan
824 1.1 jonathan case CRYPTO_MD5_HMAC:
825 1.1 jonathan axf = &auth_hash_hmac_md5_96;
826 1.1 jonathan goto authcommon;
827 1.1 jonathan case CRYPTO_SHA1_HMAC:
828 1.1 jonathan axf = &auth_hash_hmac_sha1_96;
829 1.1 jonathan goto authcommon;
830 1.1 jonathan case CRYPTO_SHA2_HMAC:
831 1.1 jonathan if (cri->cri_klen == 256)
832 1.1 jonathan axf = &auth_hash_hmac_sha2_256;
833 1.1 jonathan else if (cri->cri_klen == 384)
834 1.1 jonathan axf = &auth_hash_hmac_sha2_384;
835 1.1 jonathan else if (cri->cri_klen == 512)
836 1.1 jonathan axf = &auth_hash_hmac_sha2_512;
837 1.1 jonathan else {
838 1.1 jonathan swcr_freesession(NULL, i);
839 1.1 jonathan return EINVAL;
840 1.1 jonathan }
841 1.1 jonathan goto authcommon;
842 1.1 jonathan case CRYPTO_NULL_HMAC:
843 1.1 jonathan axf = &auth_hash_null;
844 1.1 jonathan goto authcommon;
845 1.1 jonathan case CRYPTO_RIPEMD160_HMAC:
846 1.1 jonathan axf = &auth_hash_hmac_ripemd_160_96;
847 1.1 jonathan authcommon:
848 1.1 jonathan (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
849 1.1 jonathan M_NOWAIT);
850 1.1 jonathan if ((*swd)->sw_ictx == NULL) {
851 1.1 jonathan swcr_freesession(NULL, i);
852 1.1 jonathan return ENOBUFS;
853 1.1 jonathan }
854 1.1 jonathan
855 1.1 jonathan (*swd)->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA,
856 1.1 jonathan M_NOWAIT);
857 1.1 jonathan if ((*swd)->sw_octx == NULL) {
858 1.1 jonathan swcr_freesession(NULL, i);
859 1.1 jonathan return ENOBUFS;
860 1.1 jonathan }
861 1.1 jonathan
862 1.1 jonathan for (k = 0; k < cri->cri_klen / 8; k++)
863 1.1 jonathan cri->cri_key[k] ^= HMAC_IPAD_VAL;
864 1.1 jonathan
865 1.1 jonathan axf->Init((*swd)->sw_ictx);
866 1.1 jonathan axf->Update((*swd)->sw_ictx, cri->cri_key,
867 1.1 jonathan cri->cri_klen / 8);
868 1.1 jonathan axf->Update((*swd)->sw_ictx, hmac_ipad_buffer,
869 1.1 jonathan HMAC_BLOCK_LEN - (cri->cri_klen / 8));
870 1.1 jonathan
871 1.1 jonathan for (k = 0; k < cri->cri_klen / 8; k++)
872 1.1 jonathan cri->cri_key[k] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
873 1.1 jonathan
874 1.1 jonathan axf->Init((*swd)->sw_octx);
875 1.1 jonathan axf->Update((*swd)->sw_octx, cri->cri_key,
876 1.1 jonathan cri->cri_klen / 8);
877 1.1 jonathan axf->Update((*swd)->sw_octx, hmac_opad_buffer,
878 1.1 jonathan HMAC_BLOCK_LEN - (cri->cri_klen / 8));
879 1.1 jonathan
880 1.1 jonathan for (k = 0; k < cri->cri_klen / 8; k++)
881 1.1 jonathan cri->cri_key[k] ^= HMAC_OPAD_VAL;
882 1.1 jonathan (*swd)->sw_axf = axf;
883 1.1 jonathan break;
884 1.1 jonathan
885 1.1 jonathan case CRYPTO_MD5_KPDK:
886 1.1 jonathan axf = &auth_hash_key_md5;
887 1.1 jonathan goto auth2common;
888 1.1 jonathan
889 1.1 jonathan case CRYPTO_SHA1_KPDK:
890 1.1 jonathan axf = &auth_hash_key_sha1;
891 1.1 jonathan auth2common:
892 1.1 jonathan (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
893 1.1 jonathan M_NOWAIT);
894 1.1 jonathan if ((*swd)->sw_ictx == NULL) {
895 1.1 jonathan swcr_freesession(NULL, i);
896 1.1 jonathan return ENOBUFS;
897 1.1 jonathan }
898 1.1 jonathan
899 1.1 jonathan /* Store the key so we can "append" it to the payload */
900 1.1 jonathan (*swd)->sw_octx = malloc(cri->cri_klen / 8, M_CRYPTO_DATA,
901 1.1 jonathan M_NOWAIT);
902 1.1 jonathan if ((*swd)->sw_octx == NULL) {
903 1.1 jonathan swcr_freesession(NULL, i);
904 1.1 jonathan return ENOBUFS;
905 1.1 jonathan }
906 1.1 jonathan
907 1.1 jonathan (*swd)->sw_klen = cri->cri_klen / 8;
908 1.1 jonathan bcopy(cri->cri_key, (*swd)->sw_octx, cri->cri_klen / 8);
909 1.1 jonathan axf->Init((*swd)->sw_ictx);
910 1.1 jonathan axf->Update((*swd)->sw_ictx, cri->cri_key,
911 1.1 jonathan cri->cri_klen / 8);
912 1.1 jonathan axf->Final(NULL, (*swd)->sw_ictx);
913 1.1 jonathan (*swd)->sw_axf = axf;
914 1.1 jonathan break;
915 1.1 jonathan
916 1.1 jonathan case CRYPTO_MD5:
917 1.1 jonathan axf = &auth_hash_md5;
918 1.1 jonathan goto auth3common;
919 1.1 jonathan
920 1.1 jonathan case CRYPTO_SHA1:
921 1.1 jonathan axf = &auth_hash_sha1;
922 1.1 jonathan auth3common:
923 1.1 jonathan (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
924 1.1 jonathan M_NOWAIT);
925 1.1 jonathan if ((*swd)->sw_ictx == NULL) {
926 1.1 jonathan swcr_freesession(NULL, i);
927 1.1 jonathan return ENOBUFS;
928 1.1 jonathan }
929 1.1 jonathan
930 1.1 jonathan axf->Init((*swd)->sw_ictx);
931 1.1 jonathan (*swd)->sw_axf = axf;
932 1.1 jonathan break;
933 1.1 jonathan
934 1.1 jonathan case CRYPTO_DEFLATE_COMP:
935 1.1 jonathan cxf = &comp_algo_deflate;
936 1.1 jonathan (*swd)->sw_cxf = cxf;
937 1.1 jonathan break;
938 1.1 jonathan default:
939 1.1 jonathan swcr_freesession(NULL, i);
940 1.1 jonathan return EINVAL;
941 1.1 jonathan }
942 1.1 jonathan
943 1.1 jonathan (*swd)->sw_alg = cri->cri_alg;
944 1.1 jonathan cri = cri->cri_next;
945 1.1 jonathan swd = &((*swd)->sw_next);
946 1.1 jonathan }
947 1.1 jonathan return 0;
948 1.1 jonathan }
949 1.1 jonathan
950 1.1 jonathan /*
951 1.1 jonathan * Free a session.
952 1.1 jonathan */
953 1.1 jonathan static int
954 1.1 jonathan swcr_freesession(void *arg, u_int64_t tid)
955 1.1 jonathan {
956 1.1 jonathan struct swcr_data *swd;
957 1.1 jonathan struct enc_xform *txf;
958 1.1 jonathan struct auth_hash *axf;
959 1.1 jonathan struct comp_algo *cxf;
960 1.1 jonathan u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
961 1.1 jonathan
962 1.1 jonathan if (sid > swcr_sesnum || swcr_sessions == NULL ||
963 1.1 jonathan swcr_sessions[sid] == NULL)
964 1.1 jonathan return EINVAL;
965 1.1 jonathan
966 1.1 jonathan /* Silently accept and return */
967 1.1 jonathan if (sid == 0)
968 1.1 jonathan return 0;
969 1.1 jonathan
970 1.1 jonathan while ((swd = swcr_sessions[sid]) != NULL) {
971 1.1 jonathan swcr_sessions[sid] = swd->sw_next;
972 1.1 jonathan
973 1.1 jonathan switch (swd->sw_alg) {
974 1.1 jonathan case CRYPTO_DES_CBC:
975 1.1 jonathan case CRYPTO_3DES_CBC:
976 1.1 jonathan case CRYPTO_BLF_CBC:
977 1.1 jonathan case CRYPTO_CAST_CBC:
978 1.1 jonathan case CRYPTO_SKIPJACK_CBC:
979 1.1 jonathan case CRYPTO_RIJNDAEL128_CBC:
980 1.1 jonathan case CRYPTO_NULL_CBC:
981 1.1 jonathan txf = swd->sw_exf;
982 1.1 jonathan
983 1.1 jonathan if (swd->sw_kschedule)
984 1.1 jonathan txf->zerokey(&(swd->sw_kschedule));
985 1.1 jonathan break;
986 1.1 jonathan
987 1.1 jonathan case CRYPTO_MD5_HMAC:
988 1.1 jonathan case CRYPTO_SHA1_HMAC:
989 1.1 jonathan case CRYPTO_SHA2_HMAC:
990 1.1 jonathan case CRYPTO_RIPEMD160_HMAC:
991 1.1 jonathan case CRYPTO_NULL_HMAC:
992 1.1 jonathan axf = swd->sw_axf;
993 1.1 jonathan
994 1.1 jonathan if (swd->sw_ictx) {
995 1.1 jonathan bzero(swd->sw_ictx, axf->ctxsize);
996 1.1 jonathan free(swd->sw_ictx, M_CRYPTO_DATA);
997 1.1 jonathan }
998 1.1 jonathan if (swd->sw_octx) {
999 1.1 jonathan bzero(swd->sw_octx, axf->ctxsize);
1000 1.1 jonathan free(swd->sw_octx, M_CRYPTO_DATA);
1001 1.1 jonathan }
1002 1.1 jonathan break;
1003 1.1 jonathan
1004 1.1 jonathan case CRYPTO_MD5_KPDK:
1005 1.1 jonathan case CRYPTO_SHA1_KPDK:
1006 1.1 jonathan axf = swd->sw_axf;
1007 1.1 jonathan
1008 1.1 jonathan if (swd->sw_ictx) {
1009 1.1 jonathan bzero(swd->sw_ictx, axf->ctxsize);
1010 1.1 jonathan free(swd->sw_ictx, M_CRYPTO_DATA);
1011 1.1 jonathan }
1012 1.1 jonathan if (swd->sw_octx) {
1013 1.1 jonathan bzero(swd->sw_octx, swd->sw_klen);
1014 1.1 jonathan free(swd->sw_octx, M_CRYPTO_DATA);
1015 1.1 jonathan }
1016 1.1 jonathan break;
1017 1.1 jonathan
1018 1.1 jonathan case CRYPTO_MD5:
1019 1.1 jonathan case CRYPTO_SHA1:
1020 1.1 jonathan axf = swd->sw_axf;
1021 1.1 jonathan
1022 1.1 jonathan if (swd->sw_ictx)
1023 1.1 jonathan free(swd->sw_ictx, M_CRYPTO_DATA);
1024 1.1 jonathan break;
1025 1.1 jonathan
1026 1.1 jonathan case CRYPTO_DEFLATE_COMP:
1027 1.1 jonathan cxf = swd->sw_cxf;
1028 1.1 jonathan break;
1029 1.1 jonathan }
1030 1.1 jonathan
1031 1.1 jonathan FREE(swd, M_CRYPTO_DATA);
1032 1.1 jonathan }
1033 1.1 jonathan return 0;
1034 1.1 jonathan }
1035 1.1 jonathan
1036 1.1 jonathan /*
1037 1.1 jonathan * Process a software request.
1038 1.1 jonathan */
1039 1.1 jonathan static int
1040 1.1 jonathan swcr_process(void *arg, struct cryptop *crp, int hint)
1041 1.1 jonathan {
1042 1.1 jonathan struct cryptodesc *crd;
1043 1.1 jonathan struct swcr_data *sw;
1044 1.1 jonathan u_int32_t lid;
1045 1.1 jonathan int type;
1046 1.1 jonathan
1047 1.1 jonathan /* Sanity check */
1048 1.1 jonathan if (crp == NULL)
1049 1.1 jonathan return EINVAL;
1050 1.1 jonathan
1051 1.1 jonathan if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
1052 1.1 jonathan crp->crp_etype = EINVAL;
1053 1.1 jonathan goto done;
1054 1.1 jonathan }
1055 1.1 jonathan
1056 1.1 jonathan lid = crp->crp_sid & 0xffffffff;
1057 1.1 jonathan if (lid >= swcr_sesnum || lid == 0 || swcr_sessions[lid] == NULL) {
1058 1.1 jonathan crp->crp_etype = ENOENT;
1059 1.1 jonathan goto done;
1060 1.1 jonathan }
1061 1.1 jonathan
1062 1.1 jonathan if (crp->crp_flags & CRYPTO_F_IMBUF) {
1063 1.1 jonathan type = CRYPTO_BUF_MBUF;
1064 1.1 jonathan } else if (crp->crp_flags & CRYPTO_F_IOV) {
1065 1.1 jonathan type = CRYPTO_BUF_IOV;
1066 1.1 jonathan } else {
1067 1.1 jonathan type = CRYPTO_BUF_CONTIG;
1068 1.1 jonathan }
1069 1.1 jonathan
1070 1.1 jonathan /* Go through crypto descriptors, processing as we go */
1071 1.1 jonathan for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
1072 1.1 jonathan /*
1073 1.1 jonathan * Find the crypto context.
1074 1.1 jonathan *
1075 1.1 jonathan * XXX Note that the logic here prevents us from having
1076 1.1 jonathan * XXX the same algorithm multiple times in a session
1077 1.1 jonathan * XXX (or rather, we can but it won't give us the right
1078 1.1 jonathan * XXX results). To do that, we'd need some way of differentiating
1079 1.1 jonathan * XXX between the various instances of an algorithm (so we can
1080 1.1 jonathan * XXX locate the correct crypto context).
1081 1.1 jonathan */
1082 1.1 jonathan for (sw = swcr_sessions[lid];
1083 1.1 jonathan sw && sw->sw_alg != crd->crd_alg;
1084 1.1 jonathan sw = sw->sw_next)
1085 1.1 jonathan ;
1086 1.1 jonathan
1087 1.1 jonathan /* No such context ? */
1088 1.1 jonathan if (sw == NULL) {
1089 1.1 jonathan crp->crp_etype = EINVAL;
1090 1.1 jonathan goto done;
1091 1.1 jonathan }
1092 1.1 jonathan
1093 1.1 jonathan switch (sw->sw_alg) {
1094 1.1 jonathan case CRYPTO_DES_CBC:
1095 1.1 jonathan case CRYPTO_3DES_CBC:
1096 1.1 jonathan case CRYPTO_BLF_CBC:
1097 1.1 jonathan case CRYPTO_CAST_CBC:
1098 1.1 jonathan case CRYPTO_SKIPJACK_CBC:
1099 1.1 jonathan case CRYPTO_RIJNDAEL128_CBC:
1100 1.1 jonathan if ((crp->crp_etype = swcr_encdec(crd, sw,
1101 1.1 jonathan crp->crp_buf, type)) != 0)
1102 1.1 jonathan goto done;
1103 1.1 jonathan break;
1104 1.1 jonathan case CRYPTO_NULL_CBC:
1105 1.1 jonathan crp->crp_etype = 0;
1106 1.1 jonathan break;
1107 1.1 jonathan case CRYPTO_MD5_HMAC:
1108 1.1 jonathan case CRYPTO_SHA1_HMAC:
1109 1.1 jonathan case CRYPTO_SHA2_HMAC:
1110 1.1 jonathan case CRYPTO_RIPEMD160_HMAC:
1111 1.1 jonathan case CRYPTO_NULL_HMAC:
1112 1.1 jonathan case CRYPTO_MD5_KPDK:
1113 1.1 jonathan case CRYPTO_SHA1_KPDK:
1114 1.1 jonathan case CRYPTO_MD5:
1115 1.1 jonathan case CRYPTO_SHA1:
1116 1.1 jonathan if ((crp->crp_etype = swcr_authcompute(crp, crd, sw,
1117 1.1 jonathan crp->crp_buf, type)) != 0)
1118 1.1 jonathan goto done;
1119 1.1 jonathan break;
1120 1.1 jonathan
1121 1.1 jonathan case CRYPTO_DEFLATE_COMP:
1122 1.1 jonathan if ((crp->crp_etype = swcr_compdec(crd, sw,
1123 1.1 jonathan crp->crp_buf, type)) != 0)
1124 1.1 jonathan goto done;
1125 1.1 jonathan else
1126 1.1 jonathan crp->crp_olen = (int)sw->sw_size;
1127 1.1 jonathan break;
1128 1.1 jonathan
1129 1.1 jonathan default:
1130 1.1 jonathan /* Unknown/unsupported algorithm */
1131 1.1 jonathan crp->crp_etype = EINVAL;
1132 1.1 jonathan goto done;
1133 1.1 jonathan }
1134 1.1 jonathan }
1135 1.1 jonathan
1136 1.1 jonathan done:
1137 1.1 jonathan crypto_done(crp);
1138 1.1 jonathan return 0;
1139 1.1 jonathan }
1140 1.1 jonathan
1141 1.1 jonathan /*
1142 1.1 jonathan * Initialize the driver, called from the kernel main().
1143 1.1 jonathan */
1144 1.1 jonathan /*static*/
1145 1.1 jonathan void
1146 1.1 jonathan swcr_init(void)
1147 1.1 jonathan {
1148 1.1 jonathan swcr_id = crypto_get_driverid(CRYPTOCAP_F_SOFTWARE);
1149 1.1 jonathan if (swcr_id < 0) {
1150 1.1 jonathan /* This should never happen */
1151 1.1 jonathan panic("Software crypto device cannot initialize!");
1152 1.1 jonathan }
1153 1.1 jonathan
1154 1.1 jonathan crypto_register(swcr_id, CRYPTO_DES_CBC,
1155 1.1 jonathan 0, 0, swcr_newsession, swcr_freesession, swcr_process, NULL);
1156 1.1 jonathan #define REGISTER(alg) \
1157 1.1 jonathan crypto_register(swcr_id, alg, 0, 0, NULL, NULL, NULL, NULL)
1158 1.1 jonathan
1159 1.1 jonathan REGISTER(CRYPTO_3DES_CBC);
1160 1.1 jonathan REGISTER(CRYPTO_BLF_CBC);
1161 1.1 jonathan REGISTER(CRYPTO_CAST_CBC);
1162 1.1 jonathan REGISTER(CRYPTO_SKIPJACK_CBC);
1163 1.1 jonathan REGISTER(CRYPTO_NULL_CBC);
1164 1.1 jonathan REGISTER(CRYPTO_MD5_HMAC);
1165 1.1 jonathan REGISTER(CRYPTO_SHA1_HMAC);
1166 1.1 jonathan REGISTER(CRYPTO_SHA2_HMAC);
1167 1.1 jonathan REGISTER(CRYPTO_RIPEMD160_HMAC);
1168 1.1 jonathan REGISTER(CRYPTO_NULL_HMAC);
1169 1.1 jonathan REGISTER(CRYPTO_MD5_KPDK);
1170 1.1 jonathan REGISTER(CRYPTO_SHA1_KPDK);
1171 1.1 jonathan REGISTER(CRYPTO_MD5);
1172 1.1 jonathan REGISTER(CRYPTO_SHA1);
1173 1.1 jonathan REGISTER(CRYPTO_RIJNDAEL128_CBC);
1174 1.1 jonathan REGISTER(CRYPTO_DEFLATE_COMP);
1175 1.1 jonathan #undef REGISTER
1176 1.1 jonathan }
1177 1.1 jonathan
1178 1.1 jonathan #ifdef __FreeBSD__
1179 1.1 jonathan SYSINIT(cryptosoft_init, SI_SUB_PSEUDO, SI_ORDER_ANY, swcr_init, NULL)
1180 1.1 jonathan #endif
1181