Bug Summary

File:netinet/ip_ah.c
Warning:line 654, column 9
1st function call argument is an uninitialized value

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 ip_ah.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/netinet/ip_ah.c
1/* $OpenBSD: ip_ah.c,v 1.173 2021/12/23 22:35:11 bluhm Exp $ */
2/*
3 * The authors of this code are John Ioannidis (ji@tla.org),
4 * Angelos D. Keromytis (kermit@csd.uch.gr) and
5 * Niels Provos (provos@physnet.uni-hamburg.de).
6 *
7 * The original version of this code was written by John Ioannidis
8 * for BSD/OS in Athens, Greece, in November 1995.
9 *
10 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
11 * by Angelos D. Keromytis.
12 *
13 * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
14 * and Niels Provos.
15 *
16 * Additional features in 1999 by Angelos D. Keromytis and Niklas Hallqvist.
17 *
18 * Copyright (c) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
19 * Angelos D. Keromytis and Niels Provos.
20 * Copyright (c) 1999 Niklas Hallqvist.
21 * Copyright (c) 2001 Angelos D. Keromytis.
22 *
23 * Permission to use, copy, and modify this software with or without fee
24 * is hereby granted, provided that this entire notice is included in
25 * all copies of any software which is or includes a copy or
26 * modification of this software.
27 * You may use this code under the GNU public license if you so wish. Please
28 * contribute changes back to the authors under this freer than GPL license
29 * so that we may further the use of strong encryption without limitations to
30 * all.
31 *
32 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
33 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
34 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
35 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
36 * PURPOSE.
37 */
38
39#include "pfsync.h"
40
41#include <sys/param.h>
42#include <sys/systm.h>
43#include <sys/mbuf.h>
44#include <sys/socket.h>
45
46#include <net/if.h>
47#include <net/if_var.h>
48#include <net/bpf.h>
49
50#include <netinet/in.h>
51#include <netinet/ip.h>
52#include <netinet/ip_var.h>
53
54#ifdef INET61
55#include <netinet/ip6.h>
56#endif /* INET6 */
57
58#include <netinet/ip_ipsp.h>
59#include <netinet/ip_ah.h>
60#include <net/pfkeyv2.h>
61#include <net/if_enc.h>
62
63#if NPFSYNC1 > 0
64#include <net/pfvar.h>
65#include <net/if_pfsync.h>
66#endif /* NPFSYNC > 0 */
67
68#include <crypto/cryptodev.h>
69#include <crypto/xform.h>
70
71#include "bpfilter.h"
72
73#ifdef ENCDEBUG
74#define DPRINTF(fmt, args...)do { } while (0) \
75 do { \
76 if (encdebug) \
77 printf("%s: " fmt "\n", __func__, ## args); \
78 } while (0)
79#else
80#define DPRINTF(fmt, args...)do { } while (0) \
81 do { } while (0)
82#endif
83
84int ah_massage_headers(struct mbuf **, int, int, int, int);
85
86const unsigned char ipseczeroes[IPSEC_ZEROES_SIZE256]; /* zeroes! */
87
88
89/*
90 * ah_attach() is called from the transformation initialization code.
91 */
92int
93ah_attach(void)
94{
95 return 0;
96}
97
98/*
99 * ah_init() is called when an SPI is being set up.
100 */
101int
102ah_init(struct tdb *tdbp, const struct xformsw *xsp, struct ipsecinit *ii)
103{
104 const struct auth_hash *thash = NULL((void *)0);
105 struct cryptoini cria, crin;
106 int error;
107
108 /* Authentication operation. */
109 switch (ii->ii_authalg) {
110 case SADB_AALG_MD5HMAC2:
111 thash = &auth_hash_hmac_md5_96;
112 break;
113
114 case SADB_AALG_SHA1HMAC3:
115 thash = &auth_hash_hmac_sha1_96;
116 break;
117
118 case SADB_X_AALG_RIPEMD160HMAC8:
119 thash = &auth_hash_hmac_ripemd_160_96;
120 break;
121
122 case SADB_X_AALG_SHA2_2565:
123 thash = &auth_hash_hmac_sha2_256_128;
124 break;
125
126 case SADB_X_AALG_SHA2_3846:
127 thash = &auth_hash_hmac_sha2_384_192;
128 break;
129
130 case SADB_X_AALG_SHA2_5127:
131 thash = &auth_hash_hmac_sha2_512_256;
132 break;
133
134 default:
135 DPRINTF("unsupported authentication algorithm %d specified",do { } while (0)
136 ii->ii_authalg)do { } while (0);
137 return EINVAL22;
138 }
139
140 if (ii->ii_authkeylen != thash->keysize && thash->keysize != 0) {
141 DPRINTF("keylength %d doesn't match algorithm %s keysize (%d)",do { } while (0)
142 ii->ii_authkeylen, thash->name, thash->keysize)do { } while (0);
143 return EINVAL22;
144 }
145
146 tdbp->tdb_xform = xsp;
147 tdbp->tdb_authalgxform = thash;
148 tdbp->tdb_rpl = AH_HMAC_INITIAL_RPL1;
149
150 DPRINTF("initialized TDB with hash algorithm %s", thash->name)do { } while (0);
151
152 tdbp->tdb_amxkeylen = ii->ii_authkeylen;
153 tdbp->tdb_amxkey = malloc(tdbp->tdb_amxkeylen, M_XDATA76, M_WAITOK0x0001);
154
155 memcpy(tdbp->tdb_amxkey, ii->ii_authkey, tdbp->tdb_amxkeylen)__builtin_memcpy((tdbp->tdb_amxkey), (ii->ii_authkey), (
tdbp->tdb_amxkeylen))
;
156
157 /* Initialize crypto session. */
158 memset(&cria, 0, sizeof(cria))__builtin_memset((&cria), (0), (sizeof(cria)));
159 cria.cri_alg = tdbp->tdb_authalgxform->type;
160 cria.cri_klen = ii->ii_authkeylen * 8;
161 cria.cri_key = ii->ii_authkey;
162
163 if ((tdbp->tdb_wnd > 0) && (tdbp->tdb_flags & TDBF_ESN0x100000)) {
164 memset(&crin, 0, sizeof(crin))__builtin_memset((&crin), (0), (sizeof(crin)));
165 crin.cri_alg = CRYPTO_ESN23;
166 cria.cri_next = &crin;
167 }
168
169 KERNEL_LOCK()_kernel_lock();
170 error = crypto_newsession(&tdbp->tdb_cryptoid, &cria, 0);
171 KERNEL_UNLOCK()_kernel_unlock();
172 return error;
173}
174
175/*
176 * Paranoia.
177 */
178int
179ah_zeroize(struct tdb *tdbp)
180{
181 int error;
182
183 if (tdbp->tdb_amxkey) {
184 explicit_bzero(tdbp->tdb_amxkey, tdbp->tdb_amxkeylen);
185 free(tdbp->tdb_amxkey, M_XDATA76, tdbp->tdb_amxkeylen);
186 tdbp->tdb_amxkey = NULL((void *)0);
187 }
188
189 KERNEL_LOCK()_kernel_lock();
190 error = crypto_freesession(tdbp->tdb_cryptoid);
191 KERNEL_UNLOCK()_kernel_unlock();
192 tdbp->tdb_cryptoid = 0;
193 return error;
194}
195
196/*
197 * Massage IPv4/IPv6 headers for AH processing.
198 */
199int
200ah_massage_headers(struct mbuf **mp, int af, int skip, int alg, int out)
201{
202 struct mbuf *m = *mp;
203 unsigned char *ptr;
204 int off, count, error;
205 struct ip *ip;
206#ifdef INET61
207 struct ip6_ext *ip6e;
208 struct ip6_hdr ip6;
209 int ad, alloc, nxt, noff;
210#endif /* INET6 */
211
212 switch (af) {
213 case AF_INET2:
214 /*
215 * This is the least painful way of dealing with IPv4 header
216 * and option processing -- just make sure they're in
217 * contiguous memory.
218 */
219 m = *mp = m_pullup(m, skip);
220 if (m == NULL((void *)0)) {
221 DPRINTF("m_pullup() failed")do { } while (0);
222 ahstat_inc(ahs_hdrops);
223 error = ENOBUFS55;
224 goto drop;
225 }
226
227 /* Fix the IP header */
228 ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data));
229 ip->ip_tos = 0;
230 ip->ip_ttl = 0;
231 ip->ip_sum = 0;
232 ip->ip_off = 0;
233
234 ptr = mtod(m, unsigned char *)((unsigned char *)((m)->m_hdr.mh_data));
235
236 /* IPv4 option processing */
237 for (off = sizeof(struct ip); off < skip;) {
238 if (ptr[off] != IPOPT_EOL0 && ptr[off] != IPOPT_NOP1 &&
239 off + 1 >= skip) {
240 DPRINTF("illegal IPv4 option length "do { } while (0)
241 "for option %d",do { } while (0)
242 ptr[off])do { } while (0);
243 ahstat_inc(ahs_hdrops);
244 error = EINVAL22;
245 goto drop;
246 }
247
248 switch (ptr[off]) {
249 case IPOPT_EOL0:
250 off = skip; /* End the loop. */
251 break;
252
253 case IPOPT_NOP1:
254 off++;
255 break;
256
257 case IPOPT_SECURITY130: /* 0x82 */
258 case 0x85: /* Extended security. */
259 case 0x86: /* Commercial security. */
260 case 0x94: /* Router alert */
261 case 0x95: /* RFC1770 */
262 /* Sanity check for option length. */
263 if (ptr[off + 1] < 2) {
264 DPRINTF("illegal IPv4 option length "do { } while (0)
265 "for option %d",do { } while (0)
266 ptr[off])do { } while (0);
267 ahstat_inc(ahs_hdrops);
268 error = EINVAL22;
269 goto drop;
270 }
271
272 off += ptr[off + 1];
273 break;
274
275 case IPOPT_LSRR131:
276 case IPOPT_SSRR137:
277 /* Sanity check for option length. */
278 if (ptr[off + 1] < 2) {
279 DPRINTF("illegal IPv4 option length "do { } while (0)
280 "for option %d",do { } while (0)
281 ptr[off])do { } while (0);
282 ahstat_inc(ahs_hdrops);
283 error = EINVAL22;
284 goto drop;
285 }
286
287 /*
288 * On output, if we have either of the
289 * source routing options, we should
290 * swap the destination address of the
291 * IP header with the last address
292 * specified in the option, as that is
293 * what the destination's IP header
294 * will look like.
295 */
296 if (out &&
297 ptr[off + 1] >= 2 + sizeof(struct in_addr))
298 memcpy(&ip->ip_dst,__builtin_memcpy((&ip->ip_dst), (ptr + off + ptr[off +
1] - sizeof(struct in_addr)), (sizeof(struct in_addr)))
299 ptr + off + ptr[off + 1] -__builtin_memcpy((&ip->ip_dst), (ptr + off + ptr[off +
1] - sizeof(struct in_addr)), (sizeof(struct in_addr)))
300 sizeof(struct in_addr),__builtin_memcpy((&ip->ip_dst), (ptr + off + ptr[off +
1] - sizeof(struct in_addr)), (sizeof(struct in_addr)))
301 sizeof(struct in_addr))__builtin_memcpy((&ip->ip_dst), (ptr + off + ptr[off +
1] - sizeof(struct in_addr)), (sizeof(struct in_addr)))
;
302
303 /* FALLTHROUGH */
304 default:
305 /* Sanity check for option length. */
306 if (ptr[off + 1] < 2) {
307 DPRINTF("illegal IPv4 option length "do { } while (0)
308 "for option %d",do { } while (0)
309 ptr[off])do { } while (0);
310 ahstat_inc(ahs_hdrops);
311 error = EINVAL22;
312 goto drop;
313 }
314
315 /* Zeroize all other options. */
316 count = ptr[off + 1];
317 memset(ptr + off, 0, count)__builtin_memset((ptr + off), (0), (count));
318 off += count;
319 break;
320 }
321
322 /* Sanity check. */
323 if (off > skip) {
324 DPRINTF("malformed IPv4 options header")do { } while (0);
325 ahstat_inc(ahs_hdrops);
326 error = EINVAL22;
327 goto drop;
328 }
329 }
330
331 break;
332
333#ifdef INET61
334 case AF_INET624: /* Ugly... */
335 /* Copy and "cook" the IPv6 header. */
336 m_copydata(m, 0, sizeof(ip6), &ip6);
337
338 /* We don't do IPv6 Jumbograms. */
339 if (ip6.ip6_plenip6_ctlun.ip6_un1.ip6_un1_plen == 0) {
340 DPRINTF("unsupported IPv6 jumbogram")do { } while (0);
341 ahstat_inc(ahs_hdrops);
342 error = EMSGSIZE40;
343 goto drop;
344 }
345
346 ip6.ip6_flowip6_ctlun.ip6_un1.ip6_un1_flow = 0;
347 ip6.ip6_hlimip6_ctlun.ip6_un1.ip6_un1_hlim = 0;
348 ip6.ip6_vfcip6_ctlun.ip6_un2_vfc &= ~IPV6_VERSION_MASK0xf0;
349 ip6.ip6_vfcip6_ctlun.ip6_un2_vfc |= IPV6_VERSION0x60;
350
351 /* Scoped address handling. */
352 if (IN6_IS_SCOPE_EMBED(&ip6.ip6_src)(((((&ip6.ip6_src)->__u6_addr.__u6_addr8[0] == 0xfe) &&
(((&ip6.ip6_src)->__u6_addr.__u6_addr8[1] & 0xc0)
== 0x80))) || ((((&ip6.ip6_src)->__u6_addr.__u6_addr8
[0] == 0xff) && (((&ip6.ip6_src)->__u6_addr.__u6_addr8
[1] & 0x0f) == 0x02))) || ((((&ip6.ip6_src)->__u6_addr
.__u6_addr8[0] == 0xff) && (((&ip6.ip6_src)->__u6_addr
.__u6_addr8[1] & 0x0f) == 0x01))))
)
353 ip6.ip6_src.s6_addr16__u6_addr.__u6_addr16[1] = 0;
354 if (IN6_IS_SCOPE_EMBED(&ip6.ip6_dst)(((((&ip6.ip6_dst)->__u6_addr.__u6_addr8[0] == 0xfe) &&
(((&ip6.ip6_dst)->__u6_addr.__u6_addr8[1] & 0xc0)
== 0x80))) || ((((&ip6.ip6_dst)->__u6_addr.__u6_addr8
[0] == 0xff) && (((&ip6.ip6_dst)->__u6_addr.__u6_addr8
[1] & 0x0f) == 0x02))) || ((((&ip6.ip6_dst)->__u6_addr
.__u6_addr8[0] == 0xff) && (((&ip6.ip6_dst)->__u6_addr
.__u6_addr8[1] & 0x0f) == 0x01))))
)
355 ip6.ip6_dst.s6_addr16__u6_addr.__u6_addr16[1] = 0;
356
357 /* Done with IPv6 header. */
358 error = m_copyback(m, 0, sizeof(struct ip6_hdr), &ip6,
359 M_NOWAIT0x0002);
360 if (error) {
361 DPRINTF("m_copyback no memory")do { } while (0);
362 ahstat_inc(ahs_hdrops);
363 goto drop;
364 }
365
366 /* Let's deal with the remaining headers (if any). */
367 if (skip - sizeof(struct ip6_hdr) > 0) {
368 if (m->m_lenm_hdr.mh_len <= skip) {
369 ptr = malloc(skip - sizeof(struct ip6_hdr),
370 M_XDATA76, M_NOWAIT0x0002);
371 if (ptr == NULL((void *)0)) {
372 DPRINTF("failed to allocate "do { } while (0)
373 "memory for IPv6 headers")do { } while (0);
374 ahstat_inc(ahs_hdrops);
375 error = ENOBUFS55;
376 goto drop;
377 }
378
379 /*
380 * Copy all the protocol headers after
381 * the IPv6 header.
382 */
383 m_copydata(m, sizeof(struct ip6_hdr),
384 skip - sizeof(struct ip6_hdr), ptr);
385 alloc = 1;
386 } else {
387 /* No need to allocate memory. */
388 ptr = mtod(m, unsigned char *)((unsigned char *)((m)->m_hdr.mh_data)) +
389 sizeof(struct ip6_hdr);
390 alloc = 0;
391 }
392 } else
393 break;
394
395 nxt = ip6.ip6_nxtip6_ctlun.ip6_un1.ip6_un1_nxt; /* Next header type. */
396
397 for (off = 0; off < skip - sizeof(struct ip6_hdr);) {
398 if (off + sizeof(struct ip6_ext) >
399 skip - sizeof(struct ip6_hdr))
400 goto error6;
401 ip6e = (struct ip6_ext *)(ptr + off);
402
403 switch (nxt) {
404 case IPPROTO_HOPOPTS0:
405 case IPPROTO_DSTOPTS60:
406 noff = off + ((ip6e->ip6e_len + 1) << 3);
407
408 /* Sanity check. */
409 if (noff > skip - sizeof(struct ip6_hdr))
410 goto error6;
411
412 /*
413 * Zero out mutable options.
414 */
415 for (count = off + sizeof(struct ip6_ext);
416 count < noff;) {
417 if (ptr[count] == IP6OPT_PAD10x00) {
418 count++;
419 continue; /* Skip padding. */
420 }
421
422 if (count + 2 > noff)
423 goto error6;
424 ad = ptr[count + 1] + 2;
425 if (count + ad > noff)
426 goto error6;
427
428 /* If mutable option, zeroize. */
429 if (ptr[count] & IP6OPT_MUTABLE0x20)
430 memset(ptr + count, 0, ad)__builtin_memset((ptr + count), (0), (ad));
431
432 count += ad;
433 }
434
435 if (count != noff)
436 goto error6;
437 break;
438
439 case IPPROTO_ROUTING43:
440 /*
441 * Always include routing headers in
442 * computation.
443 */
444 {
445 struct ip6_rthdr *rh;
446
447 rh = (struct ip6_rthdr *)(ptr + off);
448 /*
449 * must adjust content to make it look like
450 * its final form (as seen at the final
451 * destination).
452 * we only know how to massage type 0 routing
453 * header.
454 */
455 if (out && rh->ip6r_type == IPV6_RTHDR_TYPE_00) {
456 struct ip6_rthdr0 *rh0;
457 struct in6_addr *addr, finaldst;
458 int i;
459
460 rh0 = (struct ip6_rthdr0 *)rh;
461 addr = (struct in6_addr *)(rh0 + 1);
462
463 for (i = 0; i < rh0->ip6r0_segleft; i++)
464 if (IN6_IS_SCOPE_EMBED(&addr[i])(((((&addr[i])->__u6_addr.__u6_addr8[0] == 0xfe) &&
(((&addr[i])->__u6_addr.__u6_addr8[1] & 0xc0) == 0x80
))) || ((((&addr[i])->__u6_addr.__u6_addr8[0] == 0xff)
&& (((&addr[i])->__u6_addr.__u6_addr8[1] &
0x0f) == 0x02))) || ((((&addr[i])->__u6_addr.__u6_addr8
[0] == 0xff) && (((&addr[i])->__u6_addr.__u6_addr8
[1] & 0x0f) == 0x01))))
)
465 addr[i].s6_addr16__u6_addr.__u6_addr16[1] = 0;
466
467 finaldst = addr[rh0->ip6r0_segleft - 1];
468 memmove(&addr[1], &addr[0],__builtin_memmove((&addr[1]), (&addr[0]), (sizeof(struct
in6_addr) * (rh0->ip6r0_segleft - 1)))
469 sizeof(struct in6_addr) *__builtin_memmove((&addr[1]), (&addr[0]), (sizeof(struct
in6_addr) * (rh0->ip6r0_segleft - 1)))
470 (rh0->ip6r0_segleft - 1))__builtin_memmove((&addr[1]), (&addr[0]), (sizeof(struct
in6_addr) * (rh0->ip6r0_segleft - 1)))
;
471
472 m_copydata(m, 0, sizeof(ip6), &ip6);
473 addr[0] = ip6.ip6_dst;
474 ip6.ip6_dst = finaldst;
475 error = m_copyback(m, 0, sizeof(ip6),
476 &ip6, M_NOWAIT0x0002);
477 if (error) {
478 if (alloc)
479 free(ptr, M_XDATA76, 0);
480 ahstat_inc(ahs_hdrops);
481 goto drop;
482 }
483 rh0->ip6r0_segleft = 0;
484 }
485 break;
486 }
487
488 default:
489 DPRINTF("unexpected IPv6 header type %d", off)do { } while (0);
490error6:
491 if (alloc)
492 free(ptr, M_XDATA76, 0);
493 ahstat_inc(ahs_hdrops);
494 error = EINVAL22;
495 goto drop;
496 }
497
498 /* Advance. */
499 off += ((ip6e->ip6e_len + 1) << 3);
500 nxt = ip6e->ip6e_nxt;
501 }
502
503 /* Copyback and free, if we allocated. */
504 if (alloc) {
505 error = m_copyback(m, sizeof(struct ip6_hdr),
506 skip - sizeof(struct ip6_hdr), ptr, M_NOWAIT0x0002);
507 free(ptr, M_XDATA76, 0);
508 if (error) {
509 ahstat_inc(ahs_hdrops);
510 goto drop;
511 }
512 }
513
514 break;
515#endif /* INET6 */
516 }
517
518 return 0;
519
520 drop:
521 m_freemp(mp);
522 return error;
523}
524
525/*
526 * ah_input() gets called to verify that an input packet
527 * passes authentication.
528 */
529int
530ah_input(struct mbuf **mp, struct tdb *tdb, int skip, int protoff)
531{
532 const struct auth_hash *ahx = tdb->tdb_authalgxform;
533 struct mbuf *m = *mp, *m1, *m0;
534 struct cryptodesc *crda = NULL((void *)0);
535 struct cryptop *crp = NULL((void *)0);
536 int roff;
537 uint32_t btsx, esn;
1
'esn' declared without an initial value
538 uint8_t *ptr = NULL((void *)0);
539 uint8_t hl;
540 int error, rplen;
541 uint64_t ibytes;
542#ifdef ENCDEBUG
543 char buf[INET6_ADDRSTRLEN46];
544#endif
545 uint8_t calc[AH_ALEN_MAX64];
546
547 rplen = AH_FLENGTH8 + sizeof(u_int32_t);
548
549 /* Save the AH header, we use it throughout. */
550 m_copydata(m, skip + offsetof(struct ah, ah_hl)__builtin_offsetof(struct ah, ah_hl), sizeof(u_int8_t), &hl);
551
552 /* Replay window checking, if applicable. */
553 if (tdb->tdb_wnd > 0) {
2
Assuming field 'tdb_wnd' is <= 0
3
Taking false branch
554 m_copydata(m, skip + offsetof(struct ah, ah_rpl)__builtin_offsetof(struct ah, ah_rpl),
555 sizeof(u_int32_t), &btsx);
556 btsx = ntohl(btsx)(__uint32_t)(__builtin_constant_p(btsx) ? (__uint32_t)(((__uint32_t
)(btsx) & 0xff) << 24 | ((__uint32_t)(btsx) & 0xff00
) << 8 | ((__uint32_t)(btsx) & 0xff0000) >> 8
| ((__uint32_t)(btsx) & 0xff000000) >> 24) : __swap32md
(btsx))
;
557
558 switch (checkreplaywindow(tdb, tdb->tdb_rpl, btsx, &esn, 0)) {
559 case 0: /* All's well. */
560 break;
561 case 1:
562 DPRINTF("replay counter wrapped for SA %s/%08x",do { } while (0)
563 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),do { } while (0)
564 ntohl(tdb->tdb_spi))do { } while (0);
565 ahstat_inc(ahs_wrap);
566 goto drop;
567 case 2:
568 DPRINTF("old packet received in SA %s/%08x",do { } while (0)
569 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),do { } while (0)
570 ntohl(tdb->tdb_spi))do { } while (0);
571 ahstat_inc(ahs_replay);
572 goto drop;
573 case 3:
574 DPRINTF("duplicate packet received in SA %s/%08x",do { } while (0)
575 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),do { } while (0)
576 ntohl(tdb->tdb_spi))do { } while (0);
577 ahstat_inc(ahs_replay);
578 goto drop;
579 default:
580 DPRINTF("bogus value from checkreplaywindow() "do { } while (0)
581 "in SA %s/%08x",do { } while (0)
582 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),do { } while (0)
583 ntohl(tdb->tdb_spi))do { } while (0);
584 ahstat_inc(ahs_replay);
585 goto drop;
586 }
587 }
588
589 /* Verify AH header length. */
590 if (hl * sizeof(u_int32_t) != ahx->authsize + rplen - AH_FLENGTH8) {
4
Assuming the condition is false
5
Taking false branch
591 DPRINTF("bad authenticator length %ld for packet in SA %s/%08x",do { } while (0)
592 hl * sizeof(u_int32_t),do { } while (0)
593 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),do { } while (0)
594 ntohl(tdb->tdb_spi))do { } while (0);
595 ahstat_inc(ahs_badauthl);
596 goto drop;
597 }
598 if (skip + ahx->authsize + rplen > m->m_pkthdrM_dat.MH.MH_pkthdr.len) {
6
Assuming the condition is false
7
Taking false branch
599 DPRINTF("bad mbuf length %d (expecting %d) for packet "do { } while (0)
600 "in SA %s/%08x",do { } while (0)
601 m->m_pkthdr.len, skip + ahx->authsize + rplen,do { } while (0)
602 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),do { } while (0)
603 ntohl(tdb->tdb_spi))do { } while (0);
604 ahstat_inc(ahs_badauthl);
605 goto drop;
606 }
607
608 /* Update the counters. */
609 ibytes = (m->m_pkthdrM_dat.MH.MH_pkthdr.len - skip - hl * sizeof(u_int32_t));
610 tdb->tdb_cur_bytes += ibytes;
611 tdbstat_add(tdb, tdb_ibytes, ibytes);
612 ahstat_add(ahs_ibytes, ibytes);
613
614 /* Hard expiration. */
615 if ((tdb->tdb_flags & TDBF_BYTES0x00004) &&
8
Assuming the condition is false
616 (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes)) {
617 ipsecstat_inc(ipsec_exctdb);
618 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD3);
619 tdb_delete(tdb);
620 goto drop;
621 }
622
623 /* Notify on expiration. */
624 mtx_enter(&tdb->tdb_mtx);
625 if ((tdb->tdb_flags & TDBF_SOFT_BYTES0x00100) &&
9
Assuming the condition is false
626 (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes)) {
627 tdb->tdb_flags &= ~TDBF_SOFT_BYTES0x00100; /* Turn off checking */
628 mtx_leave(&tdb->tdb_mtx);
629 /* may sleep in solock() for the pfkey socket */
630 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT4);
631 } else
632 mtx_leave(&tdb->tdb_mtx);
633
634 /* Get crypto descriptors. */
635 crp = crypto_getreq(1);
636 if (crp == NULL((void *)0)) {
10
Assuming 'crp' is not equal to NULL
11
Taking false branch
637 DPRINTF("failed to acquire crypto descriptors")do { } while (0);
638 ahstat_inc(ahs_crypto);
639 goto drop;
640 }
641
642 crda = &crp->crp_desc[0];
643
644 crda->crd_skip = 0;
645 crda->crd_len = m->m_pkthdrM_dat.MH.MH_pkthdr.len;
646 crda->crd_inject = skip + rplen;
647
648 /* Authentication operation. */
649 crda->crd_algCRD_INI.cri_alg = ahx->type;
650 crda->crd_keyCRD_INI.cri_key = tdb->tdb_amxkey;
651 crda->crd_klenCRD_INI.cri_klen = tdb->tdb_amxkeylen * 8;
652
653 if ((tdb->tdb_wnd > 0) && (tdb->tdb_flags & TDBF_ESN0x100000)) {
12
Assuming field 'tdb_wnd' is > 0
13
Assuming the condition is true
14
Taking true branch
654 esn = htonl(esn)(__uint32_t)(__builtin_constant_p(esn) ? (__uint32_t)(((__uint32_t
)(esn) & 0xff) << 24 | ((__uint32_t)(esn) & 0xff00
) << 8 | ((__uint32_t)(esn) & 0xff0000) >> 8 |
((__uint32_t)(esn) & 0xff000000) >> 24) : __swap32md
(esn))
;
15
1st function call argument is an uninitialized value
655 memcpy(crda->crd_esn, &esn, 4)__builtin_memcpy((crda->CRD_INI.u.esn), (&esn), (4));
656 crda->crd_flags |= CRD_F_ESN0x20;
657 }
658
659 /* Allocate IPsec-specific opaque crypto info. */
660 ptr = malloc(skip + rplen + ahx->authsize, M_XDATA76, M_NOWAIT0x0002 | M_ZERO0x0008);
661 if (ptr == NULL((void *)0)) {
662 DPRINTF("failed to allocate buffer")do { } while (0);
663 ahstat_inc(ahs_crypto);
664 goto drop;
665 }
666
667 /*
668 * Save the authenticator, the skipped portion of the packet,
669 * and the AH header.
670 */
671 m_copydata(m, 0, skip + rplen + ahx->authsize, ptr);
672
673 /* Zeroize the authenticator on the packet. */
674 m_copyback(m, skip + rplen, ahx->authsize, ipseczeroes, M_NOWAIT0x0002);
675
676 /* "Massage" the packet headers for crypto processing. */
677 error = ah_massage_headers(mp, tdb->tdb_dst.sa.sa_family, skip,
678 ahx->type, 0);
679 /* callee may change or free mbuf */
680 m = *mp;
681 if (error)
682 goto drop;
683
684 /* Crypto operation descriptor. */
685 crp->crp_ilen = m->m_pkthdrM_dat.MH.MH_pkthdr.len; /* Total input length. */
686 crp->crp_flags = CRYPTO_F_IMBUF0x0001 | CRYPTO_F_MPSAFE0x0004;
687 crp->crp_buf = (caddr_t)m;
688 crp->crp_sid = tdb->tdb_cryptoid;
689
690 while ((error = crypto_invoke(crp)) == EAGAIN35) {
691 /* Reset the session ID */
692 if (tdb->tdb_cryptoid != 0)
693 tdb->tdb_cryptoid = crp->crp_sid;
694 }
695 if (error) {
696 DPRINTF("crypto error %d", error)do { } while (0);
697 ipsecstat_inc(ipsec_noxform);
698 goto drop;
699 }
700
701 /* Release the crypto descriptors */
702 crypto_freereq(crp);
703 crp = NULL((void *)0);
704
705 /* Copy authenticator off the packet. */
706 m_copydata(m, skip + rplen, ahx->authsize, calc);
707
708 /* Verify authenticator. */
709 if (timingsafe_bcmp(ptr + skip + rplen, calc, ahx->authsize)) {
710 DPRINTF("authentication failed for packet in SA %s/%08x",do { } while (0)
711 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),do { } while (0)
712 ntohl(tdb->tdb_spi))do { } while (0);
713 ahstat_inc(ahs_badauth);
714 goto drop;
715 }
716
717 /* Fix the Next Protocol field. */
718 ptr[protoff] = ptr[skip];
719
720 /* Copyback the saved (uncooked) network headers. */
721 m_copyback(m, 0, skip, ptr, M_NOWAIT0x0002);
722
723 free(ptr, M_XDATA76, 0);
724 ptr = NULL((void *)0);
725
726 /* Replay window checking, if applicable. */
727 if (tdb->tdb_wnd > 0) {
728 m_copydata(m, skip + offsetof(struct ah, ah_rpl)__builtin_offsetof(struct ah, ah_rpl),
729 sizeof(u_int32_t), &btsx);
730 btsx = ntohl(btsx)(__uint32_t)(__builtin_constant_p(btsx) ? (__uint32_t)(((__uint32_t
)(btsx) & 0xff) << 24 | ((__uint32_t)(btsx) & 0xff00
) << 8 | ((__uint32_t)(btsx) & 0xff0000) >> 8
| ((__uint32_t)(btsx) & 0xff000000) >> 24) : __swap32md
(btsx))
;
731
732 switch (checkreplaywindow(tdb, tdb->tdb_rpl, btsx, &esn, 1)) {
733 case 0: /* All's well. */
734#if NPFSYNC1 > 0
735 pfsync_update_tdb(tdb,0);
736#endif
737 break;
738 case 1:
739 DPRINTF("replay counter wrapped for SA %s/%08x",do { } while (0)
740 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),do { } while (0)
741 ntohl(tdb->tdb_spi))do { } while (0);
742 ahstat_inc(ahs_wrap);
743 goto drop;
744 case 2:
745 DPRINTF("old packet received in SA %s/%08x",do { } while (0)
746 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),do { } while (0)
747 ntohl(tdb->tdb_spi))do { } while (0);
748 ahstat_inc(ahs_replay);
749 goto drop;
750 case 3:
751 DPRINTF("duplicate packet received in SA %s/%08x",do { } while (0)
752 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),do { } while (0)
753 ntohl(tdb->tdb_spi))do { } while (0);
754 ahstat_inc(ahs_replay);
755 goto drop;
756 default:
757 DPRINTF("bogus value from checkreplaywindow() "do { } while (0)
758 "in SA %s/%08x",do { } while (0)
759 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),do { } while (0)
760 ntohl(tdb->tdb_spi))do { } while (0);
761 ahstat_inc(ahs_replay);
762 goto drop;
763 }
764 }
765
766 /* Record the beginning of the AH header. */
767 m1 = m_getptr(m, skip, &roff);
768 if (m1 == NULL((void *)0)) {
769 DPRINTF("bad mbuf chain for packet in SA %s/%08x",do { } while (0)
770 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),do { } while (0)
771 ntohl(tdb->tdb_spi))do { } while (0);
772 ahstat_inc(ahs_hdrops);
773 goto drop;
774 }
775
776 /* Remove the AH header from the mbuf. */
777 if (roff == 0) {
778 /*
779 * The AH header was conveniently at the beginning of
780 * the mbuf.
781 */
782 m_adj(m1, rplen + ahx->authsize);
783 /*
784 * If m1 is the first mbuf, it has set M_PKTHDR and m_adj()
785 * has already adjusted the packet header length for us.
786 */
787 if (m1 != m)
788 m->m_pkthdrM_dat.MH.MH_pkthdr.len -= rplen + ahx->authsize;
789 } else
790 if (roff + rplen + ahx->authsize >= m1->m_lenm_hdr.mh_len) {
791 int adjlen;
792
793 /*
794 * Part or all of the AH header is at the end
795 * of this mbuf, so first let's remove the
796 * remainder of the AH header from the
797 * beginning of the remainder of the mbuf
798 * chain, if any.
799 */
800 if (roff + rplen + ahx->authsize > m1->m_lenm_hdr.mh_len) {
801 adjlen = roff + rplen + ahx->authsize -
802 m1->m_lenm_hdr.mh_len;
803 /* Adjust the next mbuf by the remainder. */
804 m_adj(m1->m_nextm_hdr.mh_next, adjlen);
805
806 /*
807 * The second mbuf is guaranteed not
808 * to have a pkthdr...
809 */
810 m->m_pkthdrM_dat.MH.MH_pkthdr.len -= adjlen;
811 }
812
813 /* Now, let's unlink the mbuf chain for a second... */
814 m0 = m1->m_nextm_hdr.mh_next;
815 m1->m_nextm_hdr.mh_next = NULL((void *)0);
816
817 /*
818 * ...and trim the end of the first part of
819 * the chain...sick
820 */
821 adjlen = m1->m_lenm_hdr.mh_len - roff;
822 m_adj(m1, -adjlen);
823 /*
824 * If m1 is the first mbuf, it has set M_PKTHDR and
825 * m_adj() has already adjusted the packet header len.
826 */
827 if (m1 != m)
828 m->m_pkthdrM_dat.MH.MH_pkthdr.len -= adjlen;
829
830 /* Finally, let's relink. */
831 m1->m_nextm_hdr.mh_next = m0;
832 } else {
833 /*
834 * The AH header lies in the "middle" of the
835 * mbuf...do an overlapping copy of the
836 * remainder of the mbuf over the ESP header.
837 */
838 bcopy(mtod(m1, u_char *)((u_char *)((m1)->m_hdr.mh_data)) + roff + rplen +
839 ahx->authsize, mtod(m1, u_char *)((u_char *)((m1)->m_hdr.mh_data)) + roff,
840 m1->m_lenm_hdr.mh_len - (roff + rplen + ahx->authsize));
841 m1->m_lenm_hdr.mh_len -= rplen + ahx->authsize;
842 m->m_pkthdrM_dat.MH.MH_pkthdr.len -= rplen + ahx->authsize;
843 }
844
845 return ipsec_common_input_cb(mp, tdb, skip, protoff);
846
847 drop:
848 free(ptr, M_XDATA76, 0);
849 m_freemp(mp);
850 crypto_freereq(crp);
851 return IPPROTO_DONE257;
852}
853
854/*
855 * AH output routine, called by ipsp_process_packet().
856 */
857int
858ah_output(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
859{
860 const struct auth_hash *ahx = tdb->tdb_authalgxform;
861 struct cryptodesc *crda;
862 struct mbuf *mi;
863 struct cryptop *crp = NULL((void *)0);
864 uint64_t replay64;
865 uint16_t iplen;
866 int error, rplen, roff;
867 uint8_t *ptr = NULL((void *)0);
868 uint8_t prot;
869 struct ah *ah;
870#if NBPFILTER1 > 0
871 struct ifnet *encif;
872#ifdef ENCDEBUG
873 char buf[INET6_ADDRSTRLEN46];
874#endif
875
876 if ((encif = enc_getif(tdb->tdb_rdomain, tdb->tdb_tap)) != NULL((void *)0)) {
877 encif->if_opacketsif_data.ifi_opackets++;
878 encif->if_obytesif_data.ifi_obytes += m->m_pkthdrM_dat.MH.MH_pkthdr.len;
879
880 if (encif->if_bpf) {
881 struct enchdr hdr;
882
883 memset(&hdr, 0, sizeof(hdr))__builtin_memset((&hdr), (0), (sizeof(hdr)));
884
885 hdr.af = tdb->tdb_dst.sa.sa_family;
886 hdr.spi = tdb->tdb_spi;
887 hdr.flags |= M_AUTH0x0800;
888
889 bpf_mtap_hdr(encif->if_bpf, (char *)&hdr,
890 ENC_HDRLEN12, m, BPF_DIRECTION_OUT(1 << 1));
891 }
892 }
893#endif
894
895 ahstat_inc(ahs_output);
896
897 /*
898 * Check for replay counter wrap-around in automatic (not
899 * manual) keying.
900 */
901 if ((tdb->tdb_rpl == 0) && (tdb->tdb_wnd > 0)) {
902 DPRINTF("SA %s/%08x should have expired",do { } while (0)
903 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),do { } while (0)
904 ntohl(tdb->tdb_spi))do { } while (0);
905 ahstat_inc(ahs_wrap);
906 error = EINVAL22;
907 goto drop;
908 }
909
910 rplen = AH_FLENGTH8 + sizeof(u_int32_t);
911
912 switch (tdb->tdb_dst.sa.sa_family) {
913 case AF_INET2:
914 /* Check for IP maximum packet size violations. */
915 if (rplen + ahx->authsize + m->m_pkthdrM_dat.MH.MH_pkthdr.len > IP_MAXPACKET65535) {
916 DPRINTF("packet in SA %s/%08x got too big",do { } while (0)
917 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),do { } while (0)
918 ntohl(tdb->tdb_spi))do { } while (0);
919 ahstat_inc(ahs_toobig);
920 error = EMSGSIZE40;
921 goto drop;
922 }
923 break;
924
925#ifdef INET61
926 case AF_INET624:
927 /* Check for IPv6 maximum packet size violations. */
928 if (rplen + ahx->authsize + m->m_pkthdrM_dat.MH.MH_pkthdr.len > IPV6_MAXPACKET65535) {
929 DPRINTF("packet in SA %s/%08x got too big",do { } while (0)
930 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),do { } while (0)
931 ntohl(tdb->tdb_spi))do { } while (0);
932 ahstat_inc(ahs_toobig);
933 error = EMSGSIZE40;
934 goto drop;
935 }
936 break;
937#endif /* INET6 */
938
939 default:
940 DPRINTF("unknown/unsupported protocol family %d, SA %s/%08x",do { } while (0)
941 tdb->tdb_dst.sa.sa_family,do { } while (0)
942 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),do { } while (0)
943 ntohl(tdb->tdb_spi))do { } while (0);
944 ahstat_inc(ahs_nopf);
945 error = EPFNOSUPPORT46;
946 goto drop;
947 }
948
949 /* Update the counters. */
950 tdb->tdb_cur_bytes += m->m_pkthdrM_dat.MH.MH_pkthdr.len - skip;
951 ahstat_add(ahs_obytes, m->m_pkthdrM_dat.MH.MH_pkthdr.len - skip);
952
953 /* Hard expiration. */
954 if ((tdb->tdb_flags & TDBF_BYTES0x00004) &&
955 (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes)) {
956 ipsecstat_inc(ipsec_exctdb);
957 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD3);
958 tdb_delete(tdb);
959 error = EINVAL22;
960 goto drop;
961 }
962
963 /* Notify on expiration. */
964 mtx_enter(&tdb->tdb_mtx);
965 if ((tdb->tdb_flags & TDBF_SOFT_BYTES0x00100) &&
966 (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes)) {
967 tdb->tdb_flags &= ~TDBF_SOFT_BYTES0x00100; /* Turn off checking */
968 mtx_leave(&tdb->tdb_mtx);
969 /* may sleep in solock() for the pfkey socket */
970 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT4);
971 } else
972 mtx_leave(&tdb->tdb_mtx);
973
974 /*
975 * Loop through mbuf chain; if we find a readonly mbuf,
976 * copy the packet.
977 */
978 mi = m;
979 while (mi != NULL((void *)0) && !M_READONLY(mi)(((mi)->m_hdr.mh_flags & 0x0001) != 0 && (((mi
)->m_hdr.mh_flags & 0x0008) == 0 || ((mi)->M_dat.MH
.MH_dat.MH_ext.ext_nextref != (mi))))
)
980 mi = mi->m_nextm_hdr.mh_next;
981
982 if (mi != NULL((void *)0)) {
983 struct mbuf *n = m_dup_pkt(m, 0, M_DONTWAIT0x0002);
984
985 if (n == NULL((void *)0)) {
986 ahstat_inc(ahs_hdrops);
987 error = ENOBUFS55;
988 goto drop;
989 }
990
991 m_freem(m);
992 m = n;
993 }
994
995 /* Inject AH header. */
996 mi = m_makespace(m, skip, rplen + ahx->authsize, &roff);
997 if (mi == NULL((void *)0)) {
998 DPRINTF("failed to inject AH header for SA %s/%08x",do { } while (0)
999 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),do { } while (0)
1000 ntohl(tdb->tdb_spi))do { } while (0);
1001 ahstat_inc(ahs_hdrops);
1002 error = ENOBUFS55;
1003 goto drop;
1004 }
1005
1006 /*
1007 * The AH header is guaranteed by m_makespace() to be in
1008 * contiguous memory, at 'roff' of the returned mbuf.
1009 */
1010 ah = (struct ah *)(mtod(mi, caddr_t)((caddr_t)((mi)->m_hdr.mh_data)) + roff);
1011
1012 /* Initialize the AH header. */
1013 m_copydata(m, protoff, sizeof(u_int8_t), &ah->ah_nh);
1014 ah->ah_hl = (rplen + ahx->authsize - AH_FLENGTH8) / sizeof(u_int32_t);
1015 ah->ah_rv = 0;
1016 ah->ah_spi = tdb->tdb_spi;
1017
1018 /* Zeroize authenticator. */
1019 m_copyback(m, skip + rplen, ahx->authsize, ipseczeroes, M_NOWAIT0x0002);
1020
1021 replay64 = tdb->tdb_rpl++;
1022 ah->ah_rpl = htonl((u_int32_t)replay64)(__uint32_t)(__builtin_constant_p((u_int32_t)replay64) ? (__uint32_t
)(((__uint32_t)((u_int32_t)replay64) & 0xff) << 24 |
((__uint32_t)((u_int32_t)replay64) & 0xff00) << 8 |
((__uint32_t)((u_int32_t)replay64) & 0xff0000) >> 8
| ((__uint32_t)((u_int32_t)replay64) & 0xff000000) >>
24) : __swap32md((u_int32_t)replay64))
;
1023#if NPFSYNC1 > 0
1024 pfsync_update_tdb(tdb,1);
1025#endif
1026
1027 /* Get crypto descriptors. */
1028 crp = crypto_getreq(1);
1029 if (crp == NULL((void *)0)) {
1030 DPRINTF("failed to acquire crypto descriptors")do { } while (0);
1031 ahstat_inc(ahs_crypto);
1032 error = ENOBUFS55;
1033 goto drop;
1034 }
1035
1036 crda = &crp->crp_desc[0];
1037
1038 crda->crd_skip = 0;
1039 crda->crd_inject = skip + rplen;
1040 crda->crd_len = m->m_pkthdrM_dat.MH.MH_pkthdr.len;
1041
1042 /* Authentication operation. */
1043 crda->crd_algCRD_INI.cri_alg = ahx->type;
1044 crda->crd_keyCRD_INI.cri_key = tdb->tdb_amxkey;
1045 crda->crd_klenCRD_INI.cri_klen = tdb->tdb_amxkeylen * 8;
1046
1047 if ((tdb->tdb_wnd > 0) && (tdb->tdb_flags & TDBF_ESN0x100000)) {
1048 u_int32_t esn;
1049
1050 esn = htonl((u_int32_t)(replay64 >> 32))(__uint32_t)(__builtin_constant_p((u_int32_t)(replay64 >>
32)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(replay64 >>
32)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(replay64
>> 32)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t
)(replay64 >> 32)) & 0xff0000) >> 8 | ((__uint32_t
)((u_int32_t)(replay64 >> 32)) & 0xff000000) >>
24) : __swap32md((u_int32_t)(replay64 >> 32)))
;
1051 memcpy(crda->crd_esn, &esn, 4)__builtin_memcpy((crda->CRD_INI.u.esn), (&esn), (4));
1052 crda->crd_flags |= CRD_F_ESN0x20;
1053 }
1054
1055 ptr = malloc(skip, M_XDATA76, M_NOWAIT0x0002 | M_ZERO0x0008);
1056 if (ptr == NULL((void *)0)) {
1057 DPRINTF("failed to allocate buffer")do { } while (0);
1058 ahstat_inc(ahs_crypto);
1059 error = ENOBUFS55;
1060 goto drop;
1061 }
1062
1063 /* Save the skipped portion of the packet. */
1064 m_copydata(m, 0, skip, ptr);
1065
1066 /*
1067 * Fix IP header length on the header used for
1068 * authentication. We don't need to fix the original
1069 * header length as it will be fixed by our caller.
1070 */
1071 switch (tdb->tdb_dst.sa.sa_family) {
1072 case AF_INET2:
1073 memcpy((caddr_t) &iplen, ((caddr_t)ptr) +__builtin_memcpy(((caddr_t) &iplen), (((caddr_t)ptr) + __builtin_offsetof
(struct ip, ip_len)), (sizeof(u_int16_t)))
1074 offsetof(struct ip, ip_len), sizeof(u_int16_t))__builtin_memcpy(((caddr_t) &iplen), (((caddr_t)ptr) + __builtin_offsetof
(struct ip, ip_len)), (sizeof(u_int16_t)))
;
1075 iplen = htons(ntohs(iplen) + rplen + ahx->authsize)(__uint16_t)(__builtin_constant_p((__uint16_t)(__builtin_constant_p
(iplen) ? (__uint16_t)(((__uint16_t)(iplen) & 0xffU) <<
8 | ((__uint16_t)(iplen) & 0xff00U) >> 8) : __swap16md
(iplen)) + rplen + ahx->authsize) ? (__uint16_t)(((__uint16_t
)((__uint16_t)(__builtin_constant_p(iplen) ? (__uint16_t)(((__uint16_t
)(iplen) & 0xffU) << 8 | ((__uint16_t)(iplen) &
0xff00U) >> 8) : __swap16md(iplen)) + rplen + ahx->
authsize) & 0xffU) << 8 | ((__uint16_t)((__uint16_t
)(__builtin_constant_p(iplen) ? (__uint16_t)(((__uint16_t)(iplen
) & 0xffU) << 8 | ((__uint16_t)(iplen) & 0xff00U
) >> 8) : __swap16md(iplen)) + rplen + ahx->authsize
) & 0xff00U) >> 8) : __swap16md((__uint16_t)(__builtin_constant_p
(iplen) ? (__uint16_t)(((__uint16_t)(iplen) & 0xffU) <<
8 | ((__uint16_t)(iplen) & 0xff00U) >> 8) : __swap16md
(iplen)) + rplen + ahx->authsize))
;
1076 m_copyback(m, offsetof(struct ip, ip_len)__builtin_offsetof(struct ip, ip_len),
1077 sizeof(u_int16_t), &iplen, M_NOWAIT0x0002);
1078 break;
1079
1080#ifdef INET61
1081 case AF_INET624:
1082 memcpy((caddr_t) &iplen, ((caddr_t)ptr) +__builtin_memcpy(((caddr_t) &iplen), (((caddr_t)ptr) + __builtin_offsetof
(struct ip6_hdr, ip6_ctlun.ip6_un1.ip6_un1_plen)), (sizeof(u_int16_t
)))
1083 offsetof(struct ip6_hdr, ip6_plen), sizeof(u_int16_t))__builtin_memcpy(((caddr_t) &iplen), (((caddr_t)ptr) + __builtin_offsetof
(struct ip6_hdr, ip6_ctlun.ip6_un1.ip6_un1_plen)), (sizeof(u_int16_t
)))
;
1084 iplen = htons(ntohs(iplen) + rplen + ahx->authsize)(__uint16_t)(__builtin_constant_p((__uint16_t)(__builtin_constant_p
(iplen) ? (__uint16_t)(((__uint16_t)(iplen) & 0xffU) <<
8 | ((__uint16_t)(iplen) & 0xff00U) >> 8) : __swap16md
(iplen)) + rplen + ahx->authsize) ? (__uint16_t)(((__uint16_t
)((__uint16_t)(__builtin_constant_p(iplen) ? (__uint16_t)(((__uint16_t
)(iplen) & 0xffU) << 8 | ((__uint16_t)(iplen) &
0xff00U) >> 8) : __swap16md(iplen)) + rplen + ahx->
authsize) & 0xffU) << 8 | ((__uint16_t)((__uint16_t
)(__builtin_constant_p(iplen) ? (__uint16_t)(((__uint16_t)(iplen
) & 0xffU) << 8 | ((__uint16_t)(iplen) & 0xff00U
) >> 8) : __swap16md(iplen)) + rplen + ahx->authsize
) & 0xff00U) >> 8) : __swap16md((__uint16_t)(__builtin_constant_p
(iplen) ? (__uint16_t)(((__uint16_t)(iplen) & 0xffU) <<
8 | ((__uint16_t)(iplen) & 0xff00U) >> 8) : __swap16md
(iplen)) + rplen + ahx->authsize))
;
1085 m_copyback(m, offsetof(struct ip6_hdr, ip6_plen)__builtin_offsetof(struct ip6_hdr, ip6_ctlun.ip6_un1.ip6_un1_plen
)
,
1086 sizeof(u_int16_t), &iplen, M_NOWAIT0x0002);
1087 break;
1088#endif /* INET6 */
1089 }
1090
1091 /* Fix the Next Header field in saved header. */
1092 ptr[protoff] = IPPROTO_AH51;
1093
1094 /* Update the Next Protocol field in the IP header. */
1095 prot = IPPROTO_AH51;
1096 m_copyback(m, protoff, sizeof(u_int8_t), &prot, M_NOWAIT0x0002);
1097
1098 /* "Massage" the packet headers for crypto processing. */
1099 error = ah_massage_headers(&m, tdb->tdb_dst.sa.sa_family, skip,
1100 ahx->type, 1);
1101 if (error) {
1102 /* mbuf was freed by callee. */
1103 m = NULL((void *)0);
1104 goto drop;
1105 }
1106
1107 /* Crypto operation descriptor. */
1108 crp->crp_ilen = m->m_pkthdrM_dat.MH.MH_pkthdr.len; /* Total input length. */
1109 crp->crp_flags = CRYPTO_F_IMBUF0x0001 | CRYPTO_F_MPSAFE0x0004;
1110 crp->crp_buf = (caddr_t)m;
1111 crp->crp_sid = tdb->tdb_cryptoid;
1112
1113 while ((error = crypto_invoke(crp)) == EAGAIN35) {
1114 /* Reset the session ID */
1115 if (tdb->tdb_cryptoid != 0)
1116 tdb->tdb_cryptoid = crp->crp_sid;
1117 }
1118 if (error) {
1119 DPRINTF("crypto error %d", error)do { } while (0);
1120 ipsecstat_inc(ipsec_noxform);
1121 goto drop;
1122 }
1123
1124 /* Release the crypto descriptors */
1125 crypto_freereq(crp);
1126 crp = NULL((void *)0);
1127
1128 /*
1129 * Copy original headers (with the new protocol number) back
1130 * in place.
1131 */
1132 m_copyback(m, 0, skip, ptr, M_NOWAIT0x0002);
1133 free(ptr, M_XDATA76, 0);
1134 ptr = NULL((void *)0);
1135
1136 /* Call the IPsec input callback. */
1137 error = ipsp_process_done(m, tdb);
1138 if (error)
1139 ahstat_inc(ahs_outfail);
1140 return error;
1141
1142 drop:
1143 free(ptr, M_XDATA76, 0);
1144 m_freem(m);
1145 crypto_freereq(crp);
1146 return error;
1147}