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