Bug Summary

File:crypto/cryptosoft.c
Warning:line 699, column 3
Value stored to 'adj' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name cryptosoft.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -D CONFIG_DRM_AMD_DC_DCN3_0 -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/crypto/cryptosoft.c
1/* $OpenBSD: cryptosoft.c,v 1.91 2021/10/24 10:26:22 patrick Exp $ */
2
3/*
4 * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
5 *
6 * This code was written by Angelos D. Keromytis in Athens, Greece, in
7 * February 2000. Network Security Technologies Inc. (NSTI) kindly
8 * supported the development of this code.
9 *
10 * Copyright (c) 2000, 2001 Angelos D. Keromytis
11 *
12 * Permission to use, copy, and modify this software with or without fee
13 * is hereby granted, provided that this entire notice is included in
14 * all source code copies of any software which is or includes a copy or
15 * modification of this software.
16 *
17 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
18 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
19 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
20 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
21 * PURPOSE.
22 */
23
24#include <sys/param.h>
25#include <sys/systm.h>
26#include <sys/malloc.h>
27#include <sys/mbuf.h>
28#include <sys/errno.h>
29#include <crypto/md5.h>
30#include <crypto/sha1.h>
31#include <crypto/rmd160.h>
32#include <crypto/cast.h>
33#include <crypto/cryptodev.h>
34#include <crypto/cryptosoft.h>
35#include <crypto/xform.h>
36
37const u_int8_t hmac_ipad_buffer[HMAC_MAX_BLOCK_LEN128] = {
38 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
39 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
40 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
41 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
42 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
43 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
44 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
45 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
46 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
47 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
48 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
49 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
50 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
51 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
52 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
53 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
54};
55
56const u_int8_t hmac_opad_buffer[HMAC_MAX_BLOCK_LEN128] = {
57 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
58 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
59 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
60 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
61 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
62 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
63 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
64 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
65 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
66 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
67 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
68 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
69 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
70 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
71 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
72 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C
73};
74
75
76struct swcr_list *swcr_sessions = NULL((void *)0);
77u_int32_t swcr_sesnum = 0;
78int32_t swcr_id = -1;
79
80#define COPYBACK(x, a, b, c, d)do { if ((x) == 0x2) m_copyback((struct mbuf *)a,b,c,d,0x0002
); else cuio_copyback((struct uio *)a,b,c,d); } while (0)
\
81 do { \
82 if ((x) == CRYPTO_BUF_MBUF0x2) \
83 m_copyback((struct mbuf *)a,b,c,d,M_NOWAIT0x0002); \
84 else \
85 cuio_copyback((struct uio *)a,b,c,d); \
86 } while (0)
87#define COPYDATA(x, a, b, c, d)do { if ((x) == 0x2) m_copydata((struct mbuf *)a,b,c,d); else
cuio_copydata((struct uio *)a,b,c,d); } while (0)
\
88 do { \
89 if ((x) == CRYPTO_BUF_MBUF0x2) \
90 m_copydata((struct mbuf *)a,b,c,d); \
91 else \
92 cuio_copydata((struct uio *)a,b,c,d); \
93 } while (0)
94
95/*
96 * Apply a symmetric encryption/decryption algorithm.
97 */
98int
99swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
100 int outtype)
101{
102 unsigned char iv[EALG_MAX_BLOCK_LEN64], blk[EALG_MAX_BLOCK_LEN64], *idat;
103 unsigned char *ivp, *nivp, iv2[EALG_MAX_BLOCK_LEN64];
104 const struct enc_xform *exf;
105 int i, k, j, blks, ind, count, ivlen;
106 struct mbuf *m = NULL((void *)0);
107 struct uio *uio = NULL((void *)0);
108
109 exf = sw->sw_exfSWCR_UN.SWCR_ENC.SW_exf;
110 blks = exf->blocksize;
111 ivlen = exf->ivsize;
112
113 /* Check for non-padded data */
114 if (crd->crd_len % blks)
115 return EINVAL22;
116
117 if (outtype == CRYPTO_BUF_MBUF0x2)
118 m = (struct mbuf *) buf;
119 else
120 uio = (struct uio *) buf;
121
122 /* Initialize the IV */
123 if (crd->crd_flags & CRD_F_ENCRYPT0x01) {
124 /* IV explicitly provided ? */
125 if (crd->crd_flags & CRD_F_IV_EXPLICIT0x04)
126 bcopy(crd->crd_ivCRD_INI.u.iv, iv, ivlen);
127 else
128 arc4random_buf(iv, ivlen);
129
130 /* Do we need to write the IV */
131 if (!(crd->crd_flags & CRD_F_IV_PRESENT0x02))
132 COPYBACK(outtype, buf, crd->crd_inject, ivlen, iv)do { if ((outtype) == 0x2) m_copyback((struct mbuf *)buf,crd->
crd_inject,ivlen,iv,0x0002); else cuio_copyback((struct uio *
)buf,crd->crd_inject,ivlen,iv); } while (0)
;
133
134 } else { /* Decryption */
135 /* IV explicitly provided ? */
136 if (crd->crd_flags & CRD_F_IV_EXPLICIT0x04)
137 bcopy(crd->crd_ivCRD_INI.u.iv, iv, ivlen);
138 else {
139 /* Get IV off buf */
140 COPYDATA(outtype, buf, crd->crd_inject, ivlen, iv)do { if ((outtype) == 0x2) m_copydata((struct mbuf *)buf,crd->
crd_inject,ivlen,iv); else cuio_copydata((struct uio *)buf,crd
->crd_inject,ivlen,iv); } while (0)
;
141 }
142 }
143
144 ivp = iv;
145
146 /*
147 * xforms that provide a reinit method perform all IV
148 * handling themselves.
149 */
150 if (exf->reinit)
151 exf->reinit(sw->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule, iv);
152
153 if (outtype == CRYPTO_BUF_MBUF0x2) {
154 /* Find beginning of data */
155 m = m_getptr(m, crd->crd_skip, &k);
156 if (m == NULL((void *)0))
157 return EINVAL22;
158
159 i = crd->crd_len;
160
161 while (i > 0) {
162 /*
163 * If there's insufficient data at the end of
164 * an mbuf, we have to do some copying.
165 */
166 if (m->m_lenm_hdr.mh_len < k + blks && m->m_lenm_hdr.mh_len != k) {
167 m_copydata(m, k, blks, blk);
168
169 /* Actual encryption/decryption */
170 if (exf->reinit) {
171 if (crd->crd_flags & CRD_F_ENCRYPT0x01) {
172 exf->encrypt(sw->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule,
173 blk);
174 } else {
175 exf->decrypt(sw->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule,
176 blk);
177 }
178 } else if (crd->crd_flags & CRD_F_ENCRYPT0x01) {
179 /* XOR with previous block */
180 for (j = 0; j < blks; j++)
181 blk[j] ^= ivp[j];
182
183 exf->encrypt(sw->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule, blk);
184
185 /*
186 * Keep encrypted block for XOR'ing
187 * with next block
188 */
189 bcopy(blk, iv, blks);
190 ivp = iv;
191 } else { /* decrypt */
192 /*
193 * Keep encrypted block for XOR'ing
194 * with next block
195 */
196 nivp = (ivp == iv) ? iv2 : iv;
197 bcopy(blk, nivp, blks);
198
199 exf->decrypt(sw->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule, blk);
200
201 /* XOR with previous block */
202 for (j = 0; j < blks; j++)
203 blk[j] ^= ivp[j];
204 ivp = nivp;
205 }
206
207 /* Copy back decrypted block */
208 m_copyback(m, k, blks, blk, M_NOWAIT0x0002);
209
210 /* Advance pointer */
211 m = m_getptr(m, k + blks, &k);
212 if (m == NULL((void *)0))
213 return EINVAL22;
214
215 i -= blks;
216
217 /* Could be done... */
218 if (i == 0)
219 break;
220 }
221
222 /* Skip possibly empty mbufs */
223 if (k == m->m_lenm_hdr.mh_len) {
224 for (m = m->m_nextm_hdr.mh_next; m && m->m_lenm_hdr.mh_len == 0;
225 m = m->m_nextm_hdr.mh_next)
226 ;
227 k = 0;
228 }
229
230 /* Sanity check */
231 if (m == NULL((void *)0))
232 return EINVAL22;
233
234 /*
235 * Warning: idat may point to garbage here, but
236 * we only use it in the while() loop, only if
237 * there are indeed enough data.
238 */
239 idat = mtod(m, unsigned char *)((unsigned char *)((m)->m_hdr.mh_data)) + k;
240
241 while (m->m_lenm_hdr.mh_len >= k + blks && i > 0) {
242 if (exf->reinit) {
243 if (crd->crd_flags & CRD_F_ENCRYPT0x01) {
244 exf->encrypt(sw->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule,
245 idat);
246 } else {
247 exf->decrypt(sw->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule,
248 idat);
249 }
250 } else if (crd->crd_flags & CRD_F_ENCRYPT0x01) {
251 /* XOR with previous block/IV */
252 for (j = 0; j < blks; j++)
253 idat[j] ^= ivp[j];
254
255 exf->encrypt(sw->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule, idat);
256 ivp = idat;
257 } else { /* decrypt */
258 /*
259 * Keep encrypted block to be used
260 * in next block's processing.
261 */
262 nivp = (ivp == iv) ? iv2 : iv;
263 bcopy(idat, nivp, blks);
264
265 exf->decrypt(sw->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule, idat);
266
267 /* XOR with previous block/IV */
268 for (j = 0; j < blks; j++)
269 idat[j] ^= ivp[j];
270 ivp = nivp;
271 }
272
273 idat += blks;
274 k += blks;
275 i -= blks;
276 }
277 }
278 } else {
279 /* Find beginning of data */
280 count = crd->crd_skip;
281 ind = cuio_getptr(uio, count, &k);
282 if (ind == -1)
283 return EINVAL22;
284
285 i = crd->crd_len;
286
287 while (i > 0) {
288 /*
289 * If there's insufficient data at the end,
290 * we have to do some copying.
291 */
292 if (uio->uio_iov[ind].iov_len < k + blks &&
293 uio->uio_iov[ind].iov_len != k) {
294 cuio_copydata(uio, count, blks, blk);
295
296 /* Actual encryption/decryption */
297 if (exf->reinit) {
298 if (crd->crd_flags & CRD_F_ENCRYPT0x01) {
299 exf->encrypt(sw->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule,
300 blk);
301 } else {
302 exf->decrypt(sw->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule,
303 blk);
304 }
305 } else if (crd->crd_flags & CRD_F_ENCRYPT0x01) {
306 /* XOR with previous block */
307 for (j = 0; j < blks; j++)
308 blk[j] ^= ivp[j];
309
310 exf->encrypt(sw->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule, blk);
311
312 /*
313 * Keep encrypted block for XOR'ing
314 * with next block
315 */
316 bcopy(blk, iv, blks);
317 ivp = iv;
318 } else { /* decrypt */
319 /*
320 * Keep encrypted block for XOR'ing
321 * with next block
322 */
323 nivp = (ivp == iv) ? iv2 : iv;
324 bcopy(blk, nivp, blks);
325
326 exf->decrypt(sw->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule, blk);
327
328 /* XOR with previous block */
329 for (j = 0; j < blks; j++)
330 blk[j] ^= ivp[j];
331 ivp = nivp;
332 }
333
334 /* Copy back decrypted block */
335 cuio_copyback(uio, count, blks, blk);
336
337 count += blks;
338
339 /* Advance pointer */
340 ind = cuio_getptr(uio, count, &k);
341 if (ind == -1)
342 return (EINVAL22);
343
344 i -= blks;
345
346 /* Could be done... */
347 if (i == 0)
348 break;
349 }
350
351 /*
352 * Warning: idat may point to garbage here, but
353 * we only use it in the while() loop, only if
354 * there are indeed enough data.
355 */
356 idat = (char *)uio->uio_iov[ind].iov_base + k;
357
358 while (uio->uio_iov[ind].iov_len >= k + blks &&
359 i > 0) {
360 if (exf->reinit) {
361 if (crd->crd_flags & CRD_F_ENCRYPT0x01) {
362 exf->encrypt(sw->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule,
363 idat);
364 } else {
365 exf->decrypt(sw->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule,
366 idat);
367 }
368 } else if (crd->crd_flags & CRD_F_ENCRYPT0x01) {
369 /* XOR with previous block/IV */
370 for (j = 0; j < blks; j++)
371 idat[j] ^= ivp[j];
372
373 exf->encrypt(sw->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule, idat);
374 ivp = idat;
375 } else { /* decrypt */
376 /*
377 * Keep encrypted block to be used
378 * in next block's processing.
379 */
380 nivp = (ivp == iv) ? iv2 : iv;
381 bcopy(idat, nivp, blks);
382
383 exf->decrypt(sw->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule, idat);
384
385 /* XOR with previous block/IV */
386 for (j = 0; j < blks; j++)
387 idat[j] ^= ivp[j];
388 ivp = nivp;
389 }
390
391 idat += blks;
392 count += blks;
393 k += blks;
394 i -= blks;
395 }
396
397 /*
398 * Advance to the next iov if the end of the current iov
399 * is aligned with the end of a cipher block.
400 * Note that the code is equivalent to calling:
401 * ind = cuio_getptr(uio, count, &k);
402 */
403 if (i > 0 && k == uio->uio_iov[ind].iov_len) {
404 k = 0;
405 ind++;
406 if (ind >= uio->uio_iovcnt)
407 return (EINVAL22);
408 }
409 }
410 }
411
412 return 0; /* Done with encryption/decryption */
413}
414
415/*
416 * Compute keyed-hash authenticator.
417 */
418int
419swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
420 struct swcr_data *sw, caddr_t buf, int outtype)
421{
422 unsigned char aalg[AALG_MAX_RESULT_LEN64];
423 const struct auth_hash *axf;
424 union authctx ctx;
425 int err;
426
427 if (sw->sw_ictxSWCR_UN.SWCR_AUTH.SW_ictx == 0)
428 return EINVAL22;
429
430 axf = sw->sw_axfSWCR_UN.SWCR_AUTH.SW_axf;
431
432 bcopy(sw->sw_ictxSWCR_UN.SWCR_AUTH.SW_ictx, &ctx, axf->ctxsize);
433
434 if (outtype == CRYPTO_BUF_MBUF0x2)
435 err = m_apply((struct mbuf *) buf, crd->crd_skip, crd->crd_len,
436 (int (*)(caddr_t, caddr_t, unsigned int)) axf->Update,
437 (caddr_t) &ctx);
438 else
439 err = cuio_apply((struct uio *) buf, crd->crd_skip,
440 crd->crd_len,
441 (int (*)(caddr_t, caddr_t, unsigned int)) axf->Update,
442 (caddr_t) &ctx);
443
444 if (err)
445 return err;
446
447 if (crd->crd_flags & CRD_F_ESN0x20)
448 axf->Update(&ctx, crd->crd_esnCRD_INI.u.esn, 4);
449
450 switch (sw->sw_alg) {
451 case CRYPTO_MD5_HMAC4:
452 case CRYPTO_SHA1_HMAC5:
453 case CRYPTO_RIPEMD160_HMAC6:
454 case CRYPTO_SHA2_256_HMAC11:
455 case CRYPTO_SHA2_384_HMAC12:
456 case CRYPTO_SHA2_512_HMAC13:
457 if (sw->sw_octxSWCR_UN.SWCR_AUTH.SW_octx == NULL((void *)0))
458 return EINVAL22;
459
460 axf->Final(aalg, &ctx);
461 bcopy(sw->sw_octxSWCR_UN.SWCR_AUTH.SW_octx, &ctx, axf->ctxsize);
462 axf->Update(&ctx, aalg, axf->hashsize);
463 axf->Final(aalg, &ctx);
464 break;
465 }
466
467 /* Inject the authentication data */
468 if (outtype == CRYPTO_BUF_MBUF0x2)
469 COPYBACK(outtype, buf, crd->crd_inject, axf->authsize, aalg)do { if ((outtype) == 0x2) m_copyback((struct mbuf *)buf,crd->
crd_inject,axf->authsize,aalg,0x0002); else cuio_copyback(
(struct uio *)buf,crd->crd_inject,axf->authsize,aalg); }
while (0)
;
470 else
471 bcopy(aalg, crp->crp_mac, axf->authsize);
472
473 return 0;
474}
475
476/*
477 * Apply a combined encryption-authentication transformation
478 */
479int
480swcr_authenc(struct cryptop *crp)
481{
482 uint32_t blkbuf[howmany(EALG_MAX_BLOCK_LEN, sizeof(uint32_t))(((64) + ((sizeof(uint32_t)) - 1)) / (sizeof(uint32_t)))];
483 u_char *blk = (u_char *)blkbuf;
484 u_char aalg[AALG_MAX_RESULT_LEN64];
485 u_char iv[EALG_MAX_BLOCK_LEN64];
486 union authctx ctx;
487 struct cryptodesc *crd, *crda = NULL((void *)0), *crde = NULL((void *)0);
488 struct swcr_list *session;
489 struct swcr_data *sw, *swa, *swe = NULL((void *)0);
490 const struct auth_hash *axf = NULL((void *)0);
491 const struct enc_xform *exf = NULL((void *)0);
492 caddr_t buf = (caddr_t)crp->crp_buf;
493 uint32_t *blkp;
494 int aadlen, blksz, i, ivlen, outtype, len, iskip, oskip;
495
496 ivlen = blksz = iskip = oskip = 0;
497
498 session = &swcr_sessions[crp->crp_sid & 0xffffffff];
499 for (i = 0; i < crp->crp_ndesc; i++) {
500 crd = &crp->crp_desc[i];
501 SLIST_FOREACH(sw, session, sw_next)for((sw) = ((session)->slh_first); (sw) != ((void *)0); (sw
) = ((sw)->sw_next.sle_next))
{
502 if (sw->sw_alg == crd->crd_algCRD_INI.cri_alg)
503 break;
504 }
505 if (sw == NULL((void *)0))
506 return (EINVAL22);
507
508 switch (sw->sw_alg) {
509 case CRYPTO_AES_GCM_1616:
510 case CRYPTO_AES_GMAC20:
511 case CRYPTO_CHACHA20_POLY130521:
512 swe = sw;
513 crde = crd;
514 exf = swe->sw_exfSWCR_UN.SWCR_ENC.SW_exf;
515 ivlen = exf->ivsize;
516 break;
517 case CRYPTO_AES_128_GMAC17:
518 case CRYPTO_AES_192_GMAC18:
519 case CRYPTO_AES_256_GMAC19:
520 case CRYPTO_CHACHA20_POLY1305_MAC22:
521 swa = sw;
522 crda = crd;
523 axf = swa->sw_axfSWCR_UN.SWCR_AUTH.SW_axf;
524 if (swa->sw_ictxSWCR_UN.SWCR_AUTH.SW_ictx == 0)
525 return (EINVAL22);
526 bcopy(swa->sw_ictxSWCR_UN.SWCR_AUTH.SW_ictx, &ctx, axf->ctxsize);
527 blksz = axf->blocksize;
528 break;
529 default:
530 return (EINVAL22);
531 }
532 }
533 if (crde == NULL((void *)0) || crda == NULL((void *)0))
534 return (EINVAL22);
535
536 if (crp->crp_flags & CRYPTO_F_IMBUF0x0001) {
537 outtype = CRYPTO_BUF_MBUF0x2;
538 } else {
539 outtype = CRYPTO_BUF_IOV0x1;
540 }
541
542 /* Initialize the IV */
543 if (crde->crd_flags & CRD_F_ENCRYPT0x01) {
544 /* IV explicitly provided ? */
545 if (crde->crd_flags & CRD_F_IV_EXPLICIT0x04)
546 bcopy(crde->crd_ivCRD_INI.u.iv, iv, ivlen);
547 else
548 arc4random_buf(iv, ivlen);
549
550 /* Do we need to write the IV */
551 if (!(crde->crd_flags & CRD_F_IV_PRESENT0x02))
552 COPYBACK(outtype, buf, crde->crd_inject, ivlen, iv)do { if ((outtype) == 0x2) m_copyback((struct mbuf *)buf,crde
->crd_inject,ivlen,iv,0x0002); else cuio_copyback((struct uio
*)buf,crde->crd_inject,ivlen,iv); } while (0)
;
553
554 } else { /* Decryption */
555 /* IV explicitly provided ? */
556 if (crde->crd_flags & CRD_F_IV_EXPLICIT0x04)
557 bcopy(crde->crd_ivCRD_INI.u.iv, iv, ivlen);
558 else {
559 /* Get IV off buf */
560 COPYDATA(outtype, buf, crde->crd_inject, ivlen, iv)do { if ((outtype) == 0x2) m_copydata((struct mbuf *)buf,crde
->crd_inject,ivlen,iv); else cuio_copydata((struct uio *)buf
,crde->crd_inject,ivlen,iv); } while (0)
;
561 }
562 }
563
564 /* Supply MAC with IV */
565 if (axf->Reinit)
566 axf->Reinit(&ctx, iv, ivlen);
567
568 /* Supply MAC with AAD */
569 aadlen = crda->crd_len;
570 /*
571 * Section 5 of RFC 4106 specifies that AAD construction consists of
572 * {SPI, ESN, SN} whereas the real packet contains only {SPI, SN}.
573 * Unfortunately it doesn't follow a good example set in the Section
574 * 3.3.2.1 of RFC 4303 where upper part of the ESN, located in the
575 * external (to the packet) memory buffer, is processed by the hash
576 * function in the end thus allowing to retain simple programming
577 * interfaces and avoid kludges like the one below.
578 */
579 if (crda->crd_flags & CRD_F_ESN0x20) {
580 aadlen += 4;
581 /* SPI */
582 COPYDATA(outtype, buf, crda->crd_skip, 4, blk)do { if ((outtype) == 0x2) m_copydata((struct mbuf *)buf,crda
->crd_skip,4,blk); else cuio_copydata((struct uio *)buf,crda
->crd_skip,4,blk); } while (0)
;
583 iskip = 4; /* loop below will start with an offset of 4 */
584 /* ESN */
585 bcopy(crda->crd_esnCRD_INI.u.esn, blk + 4, 4);
586 oskip = iskip + 4; /* offset output buffer blk by 8 */
587 }
588 for (i = iskip; i < crda->crd_len; i += axf->hashsize) {
589 len = MIN(crda->crd_len - i, axf->hashsize - oskip)(((crda->crd_len - i)<(axf->hashsize - oskip))?(crda
->crd_len - i):(axf->hashsize - oskip))
;
590 COPYDATA(outtype, buf, crda->crd_skip + i, len, blk + oskip)do { if ((outtype) == 0x2) m_copydata((struct mbuf *)buf,crda
->crd_skip + i,len,blk + oskip); else cuio_copydata((struct
uio *)buf,crda->crd_skip + i,len,blk + oskip); } while (0
)
;
591 bzero(blk + len + oskip, axf->hashsize - len - oskip)__builtin_bzero((blk + len + oskip), (axf->hashsize - len -
oskip))
;
592 axf->Update(&ctx, blk, axf->hashsize);
593 oskip = 0; /* reset initial output offset */
594 }
595
596 if (exf->reinit)
597 exf->reinit(swe->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule, iv);
598
599 /* Do encryption/decryption with MAC */
600 for (i = 0; i < crde->crd_len; i += blksz) {
601 len = MIN(crde->crd_len - i, blksz)(((crde->crd_len - i)<(blksz))?(crde->crd_len - i):(
blksz))
;
602 if (len < blksz)
603 bzero(blk, blksz)__builtin_bzero((blk), (blksz));
604 COPYDATA(outtype, buf, crde->crd_skip + i, len, blk)do { if ((outtype) == 0x2) m_copydata((struct mbuf *)buf,crde
->crd_skip + i,len,blk); else cuio_copydata((struct uio *)
buf,crde->crd_skip + i,len,blk); } while (0)
;
605 if (crde->crd_flags & CRD_F_ENCRYPT0x01) {
606 exf->encrypt(swe->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule, blk);
607 axf->Update(&ctx, blk, len);
608 } else {
609 axf->Update(&ctx, blk, len);
610 exf->decrypt(swe->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule, blk);
611 }
612 COPYBACK(outtype, buf, crde->crd_skip + i, len, blk)do { if ((outtype) == 0x2) m_copyback((struct mbuf *)buf,crde
->crd_skip + i,len,blk,0x0002); else cuio_copyback((struct
uio *)buf,crde->crd_skip + i,len,blk); } while (0)
;
613 }
614
615 /* Do any required special finalization */
616 switch (crda->crd_algCRD_INI.cri_alg) {
617 case CRYPTO_AES_128_GMAC17:
618 case CRYPTO_AES_192_GMAC18:
619 case CRYPTO_AES_256_GMAC19:
620 /* length block */
621 bzero(blk, axf->hashsize)__builtin_bzero((blk), (axf->hashsize));
622 blkp = (uint32_t *)blk + 1;
623 *blkp = htobe32(aadlen * 8)(__uint32_t)(__builtin_constant_p(aadlen * 8) ? (__uint32_t)(
((__uint32_t)(aadlen * 8) & 0xff) << 24 | ((__uint32_t
)(aadlen * 8) & 0xff00) << 8 | ((__uint32_t)(aadlen
* 8) & 0xff0000) >> 8 | ((__uint32_t)(aadlen * 8) &
0xff000000) >> 24) : __swap32md(aadlen * 8))
;
624 blkp = (uint32_t *)blk + 3;
625 *blkp = htobe32(crde->crd_len * 8)(__uint32_t)(__builtin_constant_p(crde->crd_len * 8) ? (__uint32_t
)(((__uint32_t)(crde->crd_len * 8) & 0xff) << 24
| ((__uint32_t)(crde->crd_len * 8) & 0xff00) <<
8 | ((__uint32_t)(crde->crd_len * 8) & 0xff0000) >>
8 | ((__uint32_t)(crde->crd_len * 8) & 0xff000000) >>
24) : __swap32md(crde->crd_len * 8))
;
626 axf->Update(&ctx, blk, axf->hashsize);
627 break;
628 case CRYPTO_CHACHA20_POLY1305_MAC22:
629 /* length block */
630 bzero(blk, axf->hashsize)__builtin_bzero((blk), (axf->hashsize));
631 blkp = (uint32_t *)blk;
632 *blkp = htole32(aadlen)((__uint32_t)(aadlen));
633 blkp = (uint32_t *)blk + 2;
634 *blkp = htole32(crde->crd_len)((__uint32_t)(crde->crd_len));
635 axf->Update(&ctx, blk, axf->hashsize);
636 break;
637 }
638
639 /* Finalize MAC */
640 axf->Final(aalg, &ctx);
641
642 /* Inject the authentication data */
643 if (outtype == CRYPTO_BUF_MBUF0x2)
644 COPYBACK(outtype, buf, crda->crd_inject, axf->authsize, aalg)do { if ((outtype) == 0x2) m_copyback((struct mbuf *)buf,crda
->crd_inject,axf->authsize,aalg,0x0002); else cuio_copyback
((struct uio *)buf,crda->crd_inject,axf->authsize,aalg)
; } while (0)
;
645 else
646 bcopy(aalg, crp->crp_mac, axf->authsize);
647
648 return (0);
649}
650
651/*
652 * Apply a compression/decompression algorithm
653 */
654int
655swcr_compdec(struct cryptodesc *crd, struct swcr_data *sw,
656 caddr_t buf, int outtype)
657{
658 u_int8_t *data, *out;
659 const struct comp_algo *cxf;
660 int adj;
661 u_int32_t result;
662
663 cxf = sw->sw_cxfSWCR_UN.SWCR_COMP.SW_cxf;
664
665 /* We must handle the whole buffer of data in one time
666 * then if there is not all the data in the mbuf, we must
667 * copy in a buffer.
668 */
669
670 data = malloc(crd->crd_len, M_CRYPTO_DATA108, M_NOWAIT0x0002);
671 if (data == NULL((void *)0))
672 return (EINVAL22);
673 COPYDATA(outtype, buf, crd->crd_skip, crd->crd_len, data)do { if ((outtype) == 0x2) m_copydata((struct mbuf *)buf,crd->
crd_skip,crd->crd_len,data); else cuio_copydata((struct uio
*)buf,crd->crd_skip,crd->crd_len,data); } while (0)
;
674
675 if (crd->crd_flags & CRD_F_COMP0x10)
676 result = cxf->compress(data, crd->crd_len, &out);
677 else
678 result = cxf->decompress(data, crd->crd_len, &out);
679
680 free(data, M_CRYPTO_DATA108, crd->crd_len);
681 if (result == 0)
682 return EINVAL22;
683
684 /* Copy back the (de)compressed data. m_copyback is
685 * extending the mbuf as necessary.
686 */
687 sw->sw_sizeSWCR_UN.SWCR_COMP.SW_size = result;
688 /* Check the compressed size when doing compression */
689 if (crd->crd_flags & CRD_F_COMP0x10) {
690 if (result > crd->crd_len) {
691 /* Compression was useless, we lost time */
692 free(out, M_CRYPTO_DATA108, result);
693 return 0;
694 }
695 }
696
697 COPYBACK(outtype, buf, crd->crd_skip, result, out)do { if ((outtype) == 0x2) m_copyback((struct mbuf *)buf,crd->
crd_skip,result,out,0x0002); else cuio_copyback((struct uio *
)buf,crd->crd_skip,result,out); } while (0)
;
698 if (result < crd->crd_len) {
699 adj = result - crd->crd_len;
Value stored to 'adj' is never read
700 if (outtype == CRYPTO_BUF_MBUF0x2) {
701 adj = result - crd->crd_len;
702 m_adj((struct mbuf *)buf, adj);
703 } else {
704 struct uio *uio = (struct uio *)buf;
705 int ind;
706
707 adj = crd->crd_len - result;
708 ind = uio->uio_iovcnt - 1;
709
710 while (adj > 0 && ind >= 0) {
711 if (adj < uio->uio_iov[ind].iov_len) {
712 uio->uio_iov[ind].iov_len -= adj;
713 break;
714 }
715
716 adj -= uio->uio_iov[ind].iov_len;
717 uio->uio_iov[ind].iov_len = 0;
718 ind--;
719 uio->uio_iovcnt--;
720 }
721 }
722 }
723 free(out, M_CRYPTO_DATA108, result);
724 return 0;
725}
726
727/*
728 * Generate a new software session.
729 */
730int
731swcr_newsession(u_int32_t *sid, struct cryptoini *cri)
732{
733 struct swcr_list *session;
734 struct swcr_data *swd, *prev;
735 const struct auth_hash *axf;
736 const struct enc_xform *txf;
737 const struct comp_algo *cxf;
738 u_int32_t i;
739 int k;
740
741 if (sid == NULL((void *)0) || cri == NULL((void *)0))
742 return EINVAL22;
743
744 if (swcr_sessions != NULL((void *)0)) {
745 for (i = 1; i < swcr_sesnum; i++)
746 if (SLIST_EMPTY(&swcr_sessions[i])(((&swcr_sessions[i])->slh_first) == ((void *)0)))
747 break;
748 }
749
750 if (swcr_sessions == NULL((void *)0) || i == swcr_sesnum) {
751 if (swcr_sessions == NULL((void *)0)) {
752 i = 1; /* We leave swcr_sessions[0] empty */
753 swcr_sesnum = CRYPTO_SW_SESSIONS32;
754 } else
755 swcr_sesnum *= 2;
756
757 session = mallocarray(swcr_sesnum, sizeof(struct swcr_list),
758 M_CRYPTO_DATA108, M_NOWAIT0x0002 | M_ZERO0x0008);
759 if (session == NULL((void *)0)) {
760 /* Reset session number */
761 if (swcr_sesnum == CRYPTO_SW_SESSIONS32)
762 swcr_sesnum = 0;
763 else
764 swcr_sesnum /= 2;
765 return ENOBUFS55;
766 }
767
768 /* Copy existing sessions */
769 if (swcr_sessions) {
770 bcopy(swcr_sessions, session,
771 (swcr_sesnum / 2) * sizeof(struct swcr_list));
772 free(swcr_sessions, M_CRYPTO_DATA108,
773 (swcr_sesnum / 2) * sizeof(struct swcr_list));
774 }
775
776 swcr_sessions = session;
777 }
778
779 session = &swcr_sessions[i];
780 *sid = i;
781 prev = NULL((void *)0);
782
783 while (cri) {
784 swd = malloc(sizeof(struct swcr_data), M_CRYPTO_DATA108,
785 M_NOWAIT0x0002 | M_ZERO0x0008);
786 if (swd == NULL((void *)0)) {
787 swcr_freesession(i);
788 return ENOBUFS55;
789 }
790 if (prev == NULL((void *)0))
791 SLIST_INSERT_HEAD(session, swd, sw_next)do { (swd)->sw_next.sle_next = (session)->slh_first; (session
)->slh_first = (swd); } while (0)
;
792 else
793 SLIST_INSERT_AFTER(prev, swd, sw_next)do { (swd)->sw_next.sle_next = (prev)->sw_next.sle_next
; (prev)->sw_next.sle_next = (swd); } while (0)
;
794
795 switch (cri->cri_alg) {
796 case CRYPTO_3DES_CBC1:
797 txf = &enc_xform_3des;
798 goto enccommon;
799 case CRYPTO_BLF_CBC2:
800 txf = &enc_xform_blf;
801 goto enccommon;
802 case CRYPTO_CAST_CBC3:
803 txf = &enc_xform_cast5;
804 goto enccommon;
805 case CRYPTO_AES_CBC7:
806 txf = &enc_xform_aes;
807 goto enccommon;
808 case CRYPTO_AES_CTR14:
809 txf = &enc_xform_aes_ctr;
810 goto enccommon;
811 case CRYPTO_AES_XTS15:
812 txf = &enc_xform_aes_xts;
813 goto enccommon;
814 case CRYPTO_AES_GCM_1616:
815 txf = &enc_xform_aes_gcm;
816 goto enccommon;
817 case CRYPTO_AES_GMAC20:
818 txf = &enc_xform_aes_gmac;
819 swd->sw_exfSWCR_UN.SWCR_ENC.SW_exf = txf;
820 break;
821 case CRYPTO_CHACHA20_POLY130521:
822 txf = &enc_xform_chacha20_poly1305;
823 goto enccommon;
824 case CRYPTO_NULL9:
825 txf = &enc_xform_null;
826 goto enccommon;
827 enccommon:
828 if (txf->ctxsize > 0) {
829 swd->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule = malloc(txf->ctxsize,
830 M_CRYPTO_DATA108, M_NOWAIT0x0002 | M_ZERO0x0008);
831 if (swd->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule == NULL((void *)0)) {
832 swcr_freesession(i);
833 return EINVAL22;
834 }
835 }
836 if (txf->setkey(swd->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule, cri->cri_key,
837 cri->cri_klen / 8) < 0) {
838 swcr_freesession(i);
839 return EINVAL22;
840 }
841 swd->sw_exfSWCR_UN.SWCR_ENC.SW_exf = txf;
842 break;
843
844 case CRYPTO_MD5_HMAC4:
845 axf = &auth_hash_hmac_md5_96;
846 goto authcommon;
847 case CRYPTO_SHA1_HMAC5:
848 axf = &auth_hash_hmac_sha1_96;
849 goto authcommon;
850 case CRYPTO_RIPEMD160_HMAC6:
851 axf = &auth_hash_hmac_ripemd_160_96;
852 goto authcommon;
853 case CRYPTO_SHA2_256_HMAC11:
854 axf = &auth_hash_hmac_sha2_256_128;
855 goto authcommon;
856 case CRYPTO_SHA2_384_HMAC12:
857 axf = &auth_hash_hmac_sha2_384_192;
858 goto authcommon;
859 case CRYPTO_SHA2_512_HMAC13:
860 axf = &auth_hash_hmac_sha2_512_256;
861 goto authcommon;
862 authcommon:
863 swd->sw_ictxSWCR_UN.SWCR_AUTH.SW_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA108,
864 M_NOWAIT0x0002);
865 if (swd->sw_ictxSWCR_UN.SWCR_AUTH.SW_ictx == NULL((void *)0)) {
866 swcr_freesession(i);
867 return ENOBUFS55;
868 }
869
870 swd->sw_octxSWCR_UN.SWCR_AUTH.SW_octx = malloc(axf->ctxsize, M_CRYPTO_DATA108,
871 M_NOWAIT0x0002);
872 if (swd->sw_octxSWCR_UN.SWCR_AUTH.SW_octx == NULL((void *)0)) {
873 swcr_freesession(i);
874 return ENOBUFS55;
875 }
876
877 for (k = 0; k < cri->cri_klen / 8; k++)
878 cri->cri_key[k] ^= HMAC_IPAD_VAL0x36;
879
880 axf->Init(swd->sw_ictxSWCR_UN.SWCR_AUTH.SW_ictx);
881 axf->Update(swd->sw_ictxSWCR_UN.SWCR_AUTH.SW_ictx, cri->cri_key,
882 cri->cri_klen / 8);
883 axf->Update(swd->sw_ictxSWCR_UN.SWCR_AUTH.SW_ictx, hmac_ipad_buffer,
884 axf->blocksize - (cri->cri_klen / 8));
885
886 for (k = 0; k < cri->cri_klen / 8; k++)
887 cri->cri_key[k] ^= (HMAC_IPAD_VAL0x36 ^ HMAC_OPAD_VAL0x5C);
888
889 axf->Init(swd->sw_octxSWCR_UN.SWCR_AUTH.SW_octx);
890 axf->Update(swd->sw_octxSWCR_UN.SWCR_AUTH.SW_octx, cri->cri_key,
891 cri->cri_klen / 8);
892 axf->Update(swd->sw_octxSWCR_UN.SWCR_AUTH.SW_octx, hmac_opad_buffer,
893 axf->blocksize - (cri->cri_klen / 8));
894
895 for (k = 0; k < cri->cri_klen / 8; k++)
896 cri->cri_key[k] ^= HMAC_OPAD_VAL0x5C;
897 swd->sw_axfSWCR_UN.SWCR_AUTH.SW_axf = axf;
898 break;
899
900 case CRYPTO_AES_128_GMAC17:
901 axf = &auth_hash_gmac_aes_128;
902 goto authenccommon;
903 case CRYPTO_AES_192_GMAC18:
904 axf = &auth_hash_gmac_aes_192;
905 goto authenccommon;
906 case CRYPTO_AES_256_GMAC19:
907 axf = &auth_hash_gmac_aes_256;
908 goto authenccommon;
909 case CRYPTO_CHACHA20_POLY1305_MAC22:
910 axf = &auth_hash_chacha20_poly1305;
911 goto authenccommon;
912 authenccommon:
913 swd->sw_ictxSWCR_UN.SWCR_AUTH.SW_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA108,
914 M_NOWAIT0x0002);
915 if (swd->sw_ictxSWCR_UN.SWCR_AUTH.SW_ictx == NULL((void *)0)) {
916 swcr_freesession(i);
917 return ENOBUFS55;
918 }
919 axf->Init(swd->sw_ictxSWCR_UN.SWCR_AUTH.SW_ictx);
920 axf->Setkey(swd->sw_ictxSWCR_UN.SWCR_AUTH.SW_ictx, cri->cri_key,
921 cri->cri_klen / 8);
922 swd->sw_axfSWCR_UN.SWCR_AUTH.SW_axf = axf;
923 break;
924
925 case CRYPTO_DEFLATE_COMP8:
926 cxf = &comp_algo_deflate;
927 swd->sw_cxfSWCR_UN.SWCR_COMP.SW_cxf = cxf;
928 break;
929 case CRYPTO_ESN23:
930 /* nothing to do */
931 break;
932 default:
933 swcr_freesession(i);
934 return EINVAL22;
935 }
936
937 swd->sw_alg = cri->cri_alg;
938 cri = cri->cri_next;
939 prev = swd;
940 }
941 return 0;
942}
943
944/*
945 * Free a session.
946 */
947int
948swcr_freesession(u_int64_t tid)
949{
950 struct swcr_list *session;
951 struct swcr_data *swd;
952 const struct enc_xform *txf;
953 const struct auth_hash *axf;
954 u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
955
956 if (sid > swcr_sesnum || swcr_sessions == NULL((void *)0) ||
957 SLIST_EMPTY(&swcr_sessions[sid])(((&swcr_sessions[sid])->slh_first) == ((void *)0)))
958 return EINVAL22;
959
960 /* Silently accept and return */
961 if (sid == 0)
962 return 0;
963
964 session = &swcr_sessions[sid];
965 while (!SLIST_EMPTY(session)(((session)->slh_first) == ((void *)0))) {
966 swd = SLIST_FIRST(session)((session)->slh_first);
967 SLIST_REMOVE_HEAD(session, sw_next)do { (session)->slh_first = (session)->slh_first->sw_next
.sle_next; } while (0)
;
968
969 switch (swd->sw_alg) {
970 case CRYPTO_3DES_CBC1:
971 case CRYPTO_BLF_CBC2:
972 case CRYPTO_CAST_CBC3:
973 case CRYPTO_AES_CBC7:
974 case CRYPTO_AES_CTR14:
975 case CRYPTO_AES_XTS15:
976 case CRYPTO_AES_GCM_1616:
977 case CRYPTO_AES_GMAC20:
978 case CRYPTO_CHACHA20_POLY130521:
979 case CRYPTO_NULL9:
980 txf = swd->sw_exfSWCR_UN.SWCR_ENC.SW_exf;
981
982 if (swd->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule) {
983 explicit_bzero(swd->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule, txf->ctxsize);
984 free(swd->sw_kscheduleSWCR_UN.SWCR_ENC.SW_kschedule, M_CRYPTO_DATA108,
985 txf->ctxsize);
986 }
987 break;
988
989 case CRYPTO_MD5_HMAC4:
990 case CRYPTO_SHA1_HMAC5:
991 case CRYPTO_RIPEMD160_HMAC6:
992 case CRYPTO_SHA2_256_HMAC11:
993 case CRYPTO_SHA2_384_HMAC12:
994 case CRYPTO_SHA2_512_HMAC13:
995 axf = swd->sw_axfSWCR_UN.SWCR_AUTH.SW_axf;
996
997 if (swd->sw_ictxSWCR_UN.SWCR_AUTH.SW_ictx) {
998 explicit_bzero(swd->sw_ictxSWCR_UN.SWCR_AUTH.SW_ictx, axf->ctxsize);
999 free(swd->sw_ictxSWCR_UN.SWCR_AUTH.SW_ictx, M_CRYPTO_DATA108, axf->ctxsize);
1000 }
1001 if (swd->sw_octxSWCR_UN.SWCR_AUTH.SW_octx) {
1002 explicit_bzero(swd->sw_octxSWCR_UN.SWCR_AUTH.SW_octx, axf->ctxsize);
1003 free(swd->sw_octxSWCR_UN.SWCR_AUTH.SW_octx, M_CRYPTO_DATA108, axf->ctxsize);
1004 }
1005 break;
1006
1007 case CRYPTO_AES_128_GMAC17:
1008 case CRYPTO_AES_192_GMAC18:
1009 case CRYPTO_AES_256_GMAC19:
1010 case CRYPTO_CHACHA20_POLY1305_MAC22:
1011 axf = swd->sw_axfSWCR_UN.SWCR_AUTH.SW_axf;
1012
1013 if (swd->sw_ictxSWCR_UN.SWCR_AUTH.SW_ictx) {
1014 explicit_bzero(swd->sw_ictxSWCR_UN.SWCR_AUTH.SW_ictx, axf->ctxsize);
1015 free(swd->sw_ictxSWCR_UN.SWCR_AUTH.SW_ictx, M_CRYPTO_DATA108, axf->ctxsize);
1016 }
1017 break;
1018 }
1019
1020 free(swd, M_CRYPTO_DATA108, sizeof(*swd));
1021 }
1022 return 0;
1023}
1024
1025/*
1026 * Process a software request.
1027 */
1028int
1029swcr_process(struct cryptop *crp)
1030{
1031 struct cryptodesc *crd;
1032 struct swcr_list *session;
1033 struct swcr_data *sw;
1034 u_int32_t lid;
1035 int err = 0;
1036 int type;
1037 int i;
1038
1039 KASSERT(crp->crp_ndesc >= 1)((crp->crp_ndesc >= 1) ? (void)0 : __assert("diagnostic "
, "/usr/src/sys/crypto/cryptosoft.c", 1039, "crp->crp_ndesc >= 1"
))
;
1040
1041 if (crp->crp_buf == NULL((void *)0)) {
1042 err = EINVAL22;
1043 goto done;
1044 }
1045
1046 lid = crp->crp_sid & 0xffffffff;
1047 if (lid >= swcr_sesnum || lid == 0 ||
1048 SLIST_EMPTY(&swcr_sessions[lid])(((&swcr_sessions[lid])->slh_first) == ((void *)0))) {
1049 err = ENOENT2;
1050 goto done;
1051 }
1052
1053 if (crp->crp_flags & CRYPTO_F_IMBUF0x0001)
1054 type = CRYPTO_BUF_MBUF0x2;
1055 else
1056 type = CRYPTO_BUF_IOV0x1;
1057
1058 /* Go through crypto descriptors, processing as we go */
1059 session = &swcr_sessions[lid];
1060 for (i = 0; i < crp->crp_ndesc; i++) {
1061 crd = &crp->crp_desc[i];
1062 /*
1063 * Find the crypto context.
1064 *
1065 * XXX Note that the logic here prevents us from having
1066 * XXX the same algorithm multiple times in a session
1067 * XXX (or rather, we can but it won't give us the right
1068 * XXX results). To do that, we'd need some way of differentiating
1069 * XXX between the various instances of an algorithm (so we can
1070 * XXX locate the correct crypto context).
1071 */
1072 SLIST_FOREACH(sw, session, sw_next)for((sw) = ((session)->slh_first); (sw) != ((void *)0); (sw
) = ((sw)->sw_next.sle_next))
{
1073 if (sw->sw_alg == crd->crd_algCRD_INI.cri_alg)
1074 break;
1075 }
1076
1077 /* No such context ? */
1078 if (sw == NULL((void *)0)) {
1079 err = EINVAL22;
1080 goto done;
1081 }
1082
1083 switch (sw->sw_alg) {
1084 case CRYPTO_NULL9:
1085 break;
1086 case CRYPTO_3DES_CBC1:
1087 case CRYPTO_BLF_CBC2:
1088 case CRYPTO_CAST_CBC3:
1089 case CRYPTO_RIJNDAEL128_CBC7:
1090 case CRYPTO_AES_CTR14:
1091 case CRYPTO_AES_XTS15:
1092 if ((err = swcr_encdec(crd, sw,
1093 crp->crp_buf, type)) != 0)
1094 goto done;
1095 break;
1096 case CRYPTO_MD5_HMAC4:
1097 case CRYPTO_SHA1_HMAC5:
1098 case CRYPTO_RIPEMD160_HMAC6:
1099 case CRYPTO_SHA2_256_HMAC11:
1100 case CRYPTO_SHA2_384_HMAC12:
1101 case CRYPTO_SHA2_512_HMAC13:
1102 if ((err = swcr_authcompute(crp, crd, sw,
1103 crp->crp_buf, type)) != 0)
1104 goto done;
1105 break;
1106
1107 case CRYPTO_AES_GCM_1616:
1108 case CRYPTO_AES_GMAC20:
1109 case CRYPTO_AES_128_GMAC17:
1110 case CRYPTO_AES_192_GMAC18:
1111 case CRYPTO_AES_256_GMAC19:
1112 case CRYPTO_CHACHA20_POLY130521:
1113 case CRYPTO_CHACHA20_POLY1305_MAC22:
1114 err = swcr_authenc(crp);
1115 goto done;
1116
1117 case CRYPTO_DEFLATE_COMP8:
1118 if ((err = swcr_compdec(crd, sw,
1119 crp->crp_buf, type)) != 0)
1120 goto done;
1121 else
1122 crp->crp_olen = (int)sw->sw_sizeSWCR_UN.SWCR_COMP.SW_size;
1123 break;
1124
1125 default:
1126 /* Unknown/unsupported algorithm */
1127 err = EINVAL22;
1128 goto done;
1129 }
1130 }
1131
1132done:
1133 return err;
1134}
1135
1136/*
1137 * Initialize the driver, called from the kernel main().
1138 */
1139void
1140swcr_init(void)
1141{
1142 int algs[CRYPTO_ALGORITHM_MAX23 + 1];
1143 int flags = CRYPTOCAP_F_SOFTWARE0x02;
1144
1145 swcr_id = crypto_get_driverid(flags);
1146 if (swcr_id < 0) {
1147 /* This should never happen */
1148 panic("Software crypto device cannot initialize!");
1149 }
1150
1151 bzero(algs, sizeof(algs))__builtin_bzero((algs), (sizeof(algs)));
1152
1153 algs[CRYPTO_3DES_CBC1] = CRYPTO_ALG_FLAG_SUPPORTED0x01;
1154 algs[CRYPTO_BLF_CBC2] = CRYPTO_ALG_FLAG_SUPPORTED0x01;
1155 algs[CRYPTO_CAST_CBC3] = CRYPTO_ALG_FLAG_SUPPORTED0x01;
1156 algs[CRYPTO_MD5_HMAC4] = CRYPTO_ALG_FLAG_SUPPORTED0x01;
1157 algs[CRYPTO_SHA1_HMAC5] = CRYPTO_ALG_FLAG_SUPPORTED0x01;
1158 algs[CRYPTO_RIPEMD160_HMAC6] = CRYPTO_ALG_FLAG_SUPPORTED0x01;
1159 algs[CRYPTO_AES_CBC7] = CRYPTO_ALG_FLAG_SUPPORTED0x01;
1160 algs[CRYPTO_AES_CTR14] = CRYPTO_ALG_FLAG_SUPPORTED0x01;
1161 algs[CRYPTO_AES_XTS15] = CRYPTO_ALG_FLAG_SUPPORTED0x01;
1162 algs[CRYPTO_AES_GCM_1616] = CRYPTO_ALG_FLAG_SUPPORTED0x01;
1163 algs[CRYPTO_AES_GMAC20] = CRYPTO_ALG_FLAG_SUPPORTED0x01;
1164 algs[CRYPTO_DEFLATE_COMP8] = CRYPTO_ALG_FLAG_SUPPORTED0x01;
1165 algs[CRYPTO_NULL9] = CRYPTO_ALG_FLAG_SUPPORTED0x01;
1166 algs[CRYPTO_SHA2_256_HMAC11] = CRYPTO_ALG_FLAG_SUPPORTED0x01;
1167 algs[CRYPTO_SHA2_384_HMAC12] = CRYPTO_ALG_FLAG_SUPPORTED0x01;
1168 algs[CRYPTO_SHA2_512_HMAC13] = CRYPTO_ALG_FLAG_SUPPORTED0x01;
1169 algs[CRYPTO_AES_128_GMAC17] = CRYPTO_ALG_FLAG_SUPPORTED0x01;
1170 algs[CRYPTO_AES_192_GMAC18] = CRYPTO_ALG_FLAG_SUPPORTED0x01;
1171 algs[CRYPTO_AES_256_GMAC19] = CRYPTO_ALG_FLAG_SUPPORTED0x01;
1172 algs[CRYPTO_CHACHA20_POLY130521] = CRYPTO_ALG_FLAG_SUPPORTED0x01;
1173 algs[CRYPTO_CHACHA20_POLY1305_MAC22] = CRYPTO_ALG_FLAG_SUPPORTED0x01;
1174 algs[CRYPTO_ESN23] = CRYPTO_ALG_FLAG_SUPPORTED0x01;
1175
1176 crypto_register(swcr_id, algs, swcr_newsession,
1177 swcr_freesession, swcr_process);
1178}