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