xform_ah.c revision 1.3 1 /* $NetBSD: xform_ah.c,v 1.3 2003/09/12 11:21:00 itojun Exp $ */
2 /* $FreeBSD: src/sys/netipsec/xform_ah.c,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $ */
3 /* $OpenBSD: ip_ah.c,v 1.63 2001/06/26 06:18:58 angelos Exp $ */
4 /*
5 * The authors of this code are John Ioannidis (ji (at) tla.org),
6 * Angelos D. Keromytis (kermit (at) csd.uch.gr) and
7 * Niels Provos (provos (at) physnet.uni-hamburg.de).
8 *
9 * The original version of this code was written by John Ioannidis
10 * for BSD/OS in Athens, Greece, in November 1995.
11 *
12 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
13 * by Angelos D. Keromytis.
14 *
15 * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
16 * and Niels Provos.
17 *
18 * Additional features in 1999 by Angelos D. Keromytis and Niklas Hallqvist.
19 *
20 * Copyright (c) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
21 * Angelos D. Keromytis and Niels Provos.
22 * Copyright (c) 1999 Niklas Hallqvist.
23 * Copyright (c) 2001 Angelos D. Keromytis.
24 *
25 * Permission to use, copy, and modify this software with or without fee
26 * is hereby granted, provided that this entire notice is included in
27 * all copies of any software which is or includes a copy or
28 * modification of this software.
29 * You may use this code under the GNU public license if you so wish. Please
30 * contribute changes back to the authors under this freer than GPL license
31 * so that we may further the use of strong encryption without limitations to
32 * all.
33 *
34 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
35 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
36 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
37 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
38 * PURPOSE.
39 */
40
41 #include <sys/cdefs.h>
42 __KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.3 2003/09/12 11:21:00 itojun Exp $");
43
44 #include "opt_inet.h"
45 #ifdef __FreeBSD__
46 #include "opt_inet6.h"
47 #endif
48
49 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/mbuf.h>
52 #include <sys/socket.h>
53 #include <sys/syslog.h>
54 #include <sys/kernel.h>
55 #include <sys/sysctl.h>
56
57 #include <net/if.h>
58
59 #include <netinet/in.h>
60 #include <netinet/in_systm.h>
61 #include <netinet/ip.h>
62 #include <netinet/ip_ecn.h>
63 #include <netinet/ip6.h>
64
65 #include <net/route.h>
66 #include <netipsec/ipsec.h>
67 #include <netipsec/ah.h>
68 #include <netipsec/ah_var.h>
69 #include <netipsec/xform.h>
70
71 #ifdef INET6
72 #include <netinet6/ip6_var.h>
73 #include <netipsec/ipsec6.h>
74 #include <netinet6/ip6_ecn.h>
75 #endif
76
77 #include <netkey/key.h>
78 #include <netkey/key_debug.h>
79 #include <netipsec/ipsec_osdep.h>
80
81 #include <opencrypto/cryptodev.h>
82
83 /*
84 * Return header size in bytes. The old protocol did not support
85 * the replay counter; the new protocol always includes the counter.
86 */
87 #define HDRSIZE(sav) \
88 (((sav)->flags & SADB_X_EXT_OLD) ? \
89 sizeof (struct ah) : sizeof (struct ah) + sizeof (u_int32_t))
90 /*
91 * Return authenticator size in bytes. The old protocol is known
92 * to use a fixed 16-byte authenticator. The new algorithm gets
93 * this size from the xform but is (currently) always 12.
94 */
95 #define AUTHSIZE(sav) \
96 ((sav->flags & SADB_X_EXT_OLD) ? 16 : (sav)->tdb_authalgxform->authsize)
97
98 int ah_enable = 1; /* control flow of packets with AH */
99 int ah_cleartos = 1; /* clear ip_tos when doing AH calc */
100 struct ahstat ahstat;
101
102 #ifdef __FreeBSD__
103 SYSCTL_DECL(_net_inet_ah);
104 SYSCTL_INT(_net_inet_ah, OID_AUTO,
105 ah_enable, CTLFLAG_RW, &ah_enable, 0, "");
106 SYSCTL_INT(_net_inet_ah, OID_AUTO,
107 ah_cleartos, CTLFLAG_RW, &ah_cleartos, 0, "");
108 SYSCTL_STRUCT(_net_inet_ah, IPSECCTL_STATS,
109 stats, CTLFLAG_RD, &ahstat, ahstat, "");
110
111 #endif __FreeBSD__
112
113 static unsigned char ipseczeroes[256]; /* larger than an ip6 extension hdr */
114
115 static int ah_input_cb(struct cryptop*);
116 static int ah_output_cb(struct cryptop*);
117
118 /*
119 * NB: this is public for use by the PF_KEY support.
120 */
121 struct auth_hash *
122 ah_algorithm_lookup(int alg)
123 {
124 if (alg >= AH_ALG_MAX)
125 return NULL;
126 switch (alg) {
127 case SADB_X_AALG_NULL:
128 return &auth_hash_null;
129 case SADB_AALG_MD5HMAC:
130 return &auth_hash_hmac_md5_96;
131 case SADB_AALG_SHA1HMAC:
132 return &auth_hash_hmac_sha1_96;
133 case SADB_X_AALG_RIPEMD160HMAC:
134 return &auth_hash_hmac_ripemd_160_96;
135 case SADB_X_AALG_MD5:
136 return &auth_hash_key_md5;
137 case SADB_X_AALG_SHA:
138 return &auth_hash_key_sha1;
139 case SADB_X_AALG_SHA2_256:
140 return &auth_hash_hmac_sha2_256;
141 case SADB_X_AALG_SHA2_384:
142 return &auth_hash_hmac_sha2_384;
143 case SADB_X_AALG_SHA2_512:
144 return &auth_hash_hmac_sha2_512;
145 }
146 return NULL;
147 }
148
149 size_t
150 ah_hdrsiz(struct secasvar *sav)
151 {
152 size_t size;
153
154 if (sav != NULL) {
155 int authsize;
156 IPSEC_ASSERT(sav->tdb_authalgxform != NULL,
157 ("ah_hdrsiz: null xform"));
158 /*XXX not right for null algorithm--does it matter??*/
159 authsize = AUTHSIZE(sav);
160 size = roundup(authsize, sizeof (u_int32_t)) + HDRSIZE(sav);
161 } else {
162 /* default guess */
163 size = sizeof (struct ah) + sizeof (u_int32_t) + 16;
164 }
165 return size;
166 }
167
168 /*
169 * NB: public for use by esp_init.
170 */
171 int
172 ah_init0(struct secasvar *sav, struct xformsw *xsp, struct cryptoini *cria)
173 {
174 struct auth_hash *thash;
175 int keylen;
176
177 thash = ah_algorithm_lookup(sav->alg_auth);
178 if (thash == NULL) {
179 DPRINTF(("ah_init: unsupported authentication algorithm %u\n",
180 sav->alg_auth));
181 return EINVAL;
182 }
183 /*
184 * Verify the replay state block allocation is consistent with
185 * the protocol type. We check here so we can make assumptions
186 * later during protocol processing.
187 */
188 /* NB: replay state is setup elsewhere (sigh) */
189 if (((sav->flags&SADB_X_EXT_OLD) == 0) ^ (sav->replay != NULL)) {
190 DPRINTF(("ah_init: replay state block inconsistency, "
191 "%s algorithm %s replay state\n",
192 (sav->flags & SADB_X_EXT_OLD) ? "old" : "new",
193 sav->replay == NULL ? "without" : "with"));
194 return EINVAL;
195 }
196 if (sav->key_auth == NULL) {
197 DPRINTF(("ah_init: no authentication key for %s "
198 "algorithm\n", thash->name));
199 return EINVAL;
200 }
201 keylen = _KEYLEN(sav->key_auth);
202 if (keylen != thash->keysize && thash->keysize != 0) {
203 DPRINTF(("ah_init: invalid keylength %d, algorithm "
204 "%s requires keysize %d\n",
205 keylen, thash->name, thash->keysize));
206 return EINVAL;
207 }
208
209 sav->tdb_xform = xsp;
210 sav->tdb_authalgxform = thash;
211
212 /* Initialize crypto session. */
213 bzero(cria, sizeof (*cria));
214 cria->cri_alg = sav->tdb_authalgxform->type;
215 cria->cri_klen = _KEYBITS(sav->key_auth);
216 cria->cri_key = _KEYBUF(sav->key_auth);
217
218 return 0;
219 }
220
221 /*
222 * ah_init() is called when an SPI is being set up.
223 */
224 static int
225 ah_init(struct secasvar *sav, struct xformsw *xsp)
226 {
227 struct cryptoini cria;
228 int error;
229
230 error = ah_init0(sav, xsp, &cria);
231 return error ? error :
232 crypto_newsession(&sav->tdb_cryptoid, &cria, crypto_support);
233 }
234
235 /*
236 * Paranoia.
237 *
238 * NB: public for use by esp_zeroize (XXX).
239 */
240 int
241 ah_zeroize(struct secasvar *sav)
242 {
243 int err;
244
245 if (sav->key_auth)
246 bzero(_KEYBUF(sav->key_auth), _KEYLEN(sav->key_auth));
247
248 err = crypto_freesession(sav->tdb_cryptoid);
249 sav->tdb_cryptoid = 0;
250 sav->tdb_authalgxform = NULL;
251 sav->tdb_xform = NULL;
252 return err;
253 }
254
255 /*
256 * Massage IPv4/IPv6 headers for AH processing.
257 */
258 static int
259 ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
260 {
261 struct mbuf *m = *m0;
262 unsigned char *ptr;
263 int off, count;
264
265 #ifdef INET
266 struct ip *ip;
267 #endif /* INET */
268
269 #ifdef INET6
270 struct ip6_ext *ip6e;
271 struct ip6_hdr ip6;
272 int alloc, len, ad;
273 #endif /* INET6 */
274
275 switch (proto) {
276 #ifdef INET
277 case AF_INET:
278 /*
279 * This is the least painful way of dealing with IPv4 header
280 * and option processing -- just make sure they're in
281 * contiguous memory.
282 */
283 *m0 = m = m_pullup(m, skip);
284 if (m == NULL) {
285 DPRINTF(("ah_massage_headers: m_pullup failed\n"));
286 return ENOBUFS;
287 }
288
289 /* Fix the IP header */
290 ip = mtod(m, struct ip *);
291 if (ah_cleartos)
292 ip->ip_tos = 0;
293 ip->ip_ttl = 0;
294 ip->ip_sum = 0;
295
296 /*
297 * On input, fix ip_len which has been byte-swapped
298 * at ip_input().
299 */
300 /* On FreeBSD, ip_off and ip_len assumed in host endian. */
301 #ifdef __FreeBSD__
302 #define TOHOST(x) (x)
303 #else
304 #define TOHOST(x) (ntohs(x))
305 #endif
306 if (!out) {
307 u_int16_t inlen = ip->ip_len;
308
309 ip->ip_len = htons(TOHOST(ip->ip_len) + skip);
310 DPRINTF(("ip len: skip %d, "
311 "in %d host %d: new: raw %d host %d\n",
312 skip,
313 inlen, TOHOST(inlen),
314 ip->ip_len, ntohs(ip->ip_len)));
315
316
317 if (alg == CRYPTO_MD5_KPDK || alg == CRYPTO_SHA1_KPDK)
318 ip->ip_off = htons(TOHOST(ip->ip_off) & IP_DF);
319 else
320 ip->ip_off = 0;
321 } else {
322 if (alg == CRYPTO_MD5_KPDK || alg == CRYPTO_SHA1_KPDK)
323 ip->ip_off = htons(ntohs(ip->ip_off) & IP_DF);
324 else
325 ip->ip_off = 0;
326 }
327
328 ptr = mtod(m, unsigned char *) + sizeof(struct ip);
329
330 /* IPv4 option processing */
331 for (off = sizeof(struct ip); off < skip;) {
332 if (ptr[off] == IPOPT_EOL || ptr[off] == IPOPT_NOP ||
333 off + 1 < skip)
334 ;
335 else {
336 DPRINTF(("ah_massage_headers: illegal IPv4 "
337 "option length for option %d\n",
338 ptr[off]));
339
340 m_freem(m);
341 return EINVAL;
342 }
343
344 switch (ptr[off]) {
345 case IPOPT_EOL:
346 off = skip; /* End the loop. */
347 break;
348
349 case IPOPT_NOP:
350 off++;
351 break;
352
353 case IPOPT_SECURITY: /* 0x82 */
354 case 0x85: /* Extended security. */
355 case 0x86: /* Commercial security. */
356 case 0x94: /* Router alert */
357 case 0x95: /* RFC1770 */
358 /* Sanity check for option length. */
359 if (ptr[off + 1] < 2) {
360 DPRINTF(("ah_massage_headers: "
361 "illegal IPv4 option length for "
362 "option %d\n", ptr[off]));
363
364 m_freem(m);
365 return EINVAL;
366 }
367
368 off += ptr[off + 1];
369 break;
370
371 case IPOPT_LSRR:
372 case IPOPT_SSRR:
373 /* Sanity check for option length. */
374 if (ptr[off + 1] < 2) {
375 DPRINTF(("ah_massage_headers: "
376 "illegal IPv4 option length for "
377 "option %d\n", ptr[off]));
378
379 m_freem(m);
380 return EINVAL;
381 }
382
383 /*
384 * On output, if we have either of the
385 * source routing options, we should
386 * swap the destination address of the
387 * IP header with the last address
388 * specified in the option, as that is
389 * what the destination's IP header
390 * will look like.
391 */
392 if (out)
393 bcopy(ptr + off + ptr[off + 1] -
394 sizeof(struct in_addr),
395 &(ip->ip_dst), sizeof(struct in_addr));
396
397 /* Fall through */
398 default:
399 /* Sanity check for option length. */
400 if (ptr[off + 1] < 2) {
401 DPRINTF(("ah_massage_headers: "
402 "illegal IPv4 option length for "
403 "option %d\n", ptr[off]));
404 m_freem(m);
405 return EINVAL;
406 }
407
408 /* Zeroize all other options. */
409 count = ptr[off + 1];
410 bcopy(ipseczeroes, ptr, count);
411 off += count;
412 break;
413 }
414
415 /* Sanity check. */
416 if (off > skip) {
417 DPRINTF(("ah_massage_headers(): malformed "
418 "IPv4 options header\n"));
419
420 m_freem(m);
421 return EINVAL;
422 }
423 }
424
425 break;
426 #endif /* INET */
427
428 #ifdef INET6
429 case AF_INET6: /* Ugly... */
430 /* Copy and "cook" the IPv6 header. */
431 m_copydata(m, 0, sizeof(ip6), (caddr_t) &ip6);
432
433 /* We don't do IPv6 Jumbograms. */
434 if (ip6.ip6_plen == 0) {
435 DPRINTF(("ah_massage_headers: unsupported IPv6 jumbogram\n"));
436 m_freem(m);
437 return EMSGSIZE;
438 }
439
440 ip6.ip6_flow = 0;
441 ip6.ip6_hlim = 0;
442 ip6.ip6_vfc &= ~IPV6_VERSION_MASK;
443 ip6.ip6_vfc |= IPV6_VERSION;
444
445 /* Scoped address handling. */
446 if (IN6_IS_SCOPE_LINKLOCAL(&ip6.ip6_src))
447 ip6.ip6_src.s6_addr16[1] = 0;
448 if (IN6_IS_SCOPE_LINKLOCAL(&ip6.ip6_dst))
449 ip6.ip6_dst.s6_addr16[1] = 0;
450
451 /* Done with IPv6 header. */
452 m_copyback(m, 0, sizeof(struct ip6_hdr), (caddr_t) &ip6);
453
454 /* Let's deal with the remaining headers (if any). */
455 if (skip - sizeof(struct ip6_hdr) > 0) {
456 if (m->m_len <= skip) {
457 ptr = (unsigned char *) malloc(
458 skip - sizeof(struct ip6_hdr),
459 M_XDATA, M_NOWAIT);
460 if (ptr == NULL) {
461 DPRINTF(("ah_massage_headers: failed "
462 "to allocate memory for IPv6 "
463 "headers\n"));
464 m_freem(m);
465 return ENOBUFS;
466 }
467
468 /*
469 * Copy all the protocol headers after
470 * the IPv6 header.
471 */
472 m_copydata(m, sizeof(struct ip6_hdr),
473 skip - sizeof(struct ip6_hdr), ptr);
474 alloc = 1;
475 } else {
476 /* No need to allocate memory. */
477 ptr = mtod(m, unsigned char *) +
478 sizeof(struct ip6_hdr);
479 alloc = 0;
480 }
481 } else
482 break;
483
484 off = ip6.ip6_nxt & 0xff; /* Next header type. */
485
486 for (len = 0; len < skip - sizeof(struct ip6_hdr);)
487 switch (off) {
488 case IPPROTO_HOPOPTS:
489 case IPPROTO_DSTOPTS:
490 ip6e = (struct ip6_ext *) (ptr + len);
491
492 /*
493 * Process the mutable/immutable
494 * options -- borrows heavily from the
495 * KAME code.
496 */
497 for (count = len + sizeof(struct ip6_ext);
498 count < len + ((ip6e->ip6e_len + 1) << 3);) {
499 if (ptr[count] == IP6OPT_PAD1) {
500 count++;
501 continue; /* Skip padding. */
502 }
503
504 /* Sanity check. */
505 if (count > len +
506 ((ip6e->ip6e_len + 1) << 3)) {
507 m_freem(m);
508
509 /* Free, if we allocated. */
510 if (alloc)
511 FREE(ptr, M_XDATA);
512 return EINVAL;
513 }
514
515 ad = ptr[count + 1];
516
517 /* If mutable option, zeroize. */
518 if (ptr[count] & IP6OPT_MUTABLE)
519 bcopy(ipseczeroes, ptr + count,
520 ptr[count + 1]);
521
522 count += ad;
523
524 /* Sanity check. */
525 if (count >
526 skip - sizeof(struct ip6_hdr)) {
527 m_freem(m);
528
529 /* Free, if we allocated. */
530 if (alloc)
531 FREE(ptr, M_XDATA);
532 return EINVAL;
533 }
534 }
535
536 /* Advance. */
537 len += ((ip6e->ip6e_len + 1) << 3);
538 off = ip6e->ip6e_nxt;
539 break;
540
541 case IPPROTO_ROUTING:
542 /*
543 * Always include routing headers in
544 * computation.
545 */
546 ip6e = (struct ip6_ext *) (ptr + len);
547 len += ((ip6e->ip6e_len + 1) << 3);
548 off = ip6e->ip6e_nxt;
549 break;
550
551 default:
552 DPRINTF(("ah_massage_headers: unexpected "
553 "IPv6 header type %d", off));
554 if (alloc)
555 FREE(ptr, M_XDATA);
556 m_freem(m);
557 return EINVAL;
558 }
559
560 /* Copyback and free, if we allocated. */
561 if (alloc) {
562 m_copyback(m, sizeof(struct ip6_hdr),
563 skip - sizeof(struct ip6_hdr), ptr);
564 free(ptr, M_XDATA);
565 }
566
567 break;
568 #endif /* INET6 */
569 }
570
571 return 0;
572 }
573
574 /*
575 * ah_input() gets called to verify that an input packet
576 * passes authentication.
577 */
578 static int
579 ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
580 {
581 struct auth_hash *ahx;
582 struct tdb_ident *tdbi;
583 struct tdb_crypto *tc;
584 struct m_tag *mtag;
585 struct newah *ah;
586 int hl, rplen, authsize;
587
588 struct cryptodesc *crda;
589 struct cryptop *crp;
590
591 IPSEC_SPLASSERT_SOFTNET("ah_input");
592
593 IPSEC_ASSERT(sav != NULL, ("ah_input: null SA"));
594 IPSEC_ASSERT(sav->key_auth != NULL,
595 ("ah_input: null authentication key"));
596 IPSEC_ASSERT(sav->tdb_authalgxform != NULL,
597 ("ah_input: null authentication xform"));
598
599 /* Figure out header size. */
600 rplen = HDRSIZE(sav);
601
602 /* XXX don't pullup, just copy header */
603 IP6_EXTHDR_GET(ah, struct newah *, m, skip, rplen);
604 if (ah == NULL) {
605 DPRINTF(("ah_input: cannot pullup header\n"));
606 ahstat.ahs_hdrops++; /*XXX*/
607 m_freem(m);
608 return ENOBUFS;
609 }
610
611 /* Check replay window, if applicable. */
612 if (sav->replay && !ipsec_chkreplay(ntohl(ah->ah_seq), sav)) {
613 ahstat.ahs_replay++;
614 DPRINTF(("ah_input: packet replay failure: %s\n",
615 ipsec_logsastr(sav)));
616 m_freem(m);
617 return ENOBUFS;
618 }
619
620 /* Verify AH header length. */
621 hl = ah->ah_len * sizeof (u_int32_t);
622 ahx = sav->tdb_authalgxform;
623 authsize = AUTHSIZE(sav);
624 if (hl != authsize + rplen - sizeof (struct ah)) {
625 DPRINTF(("ah_input: bad authenticator length %u (expecting %lu)"
626 " for packet in SA %s/%08lx\n",
627 hl, (u_long) (authsize + rplen - sizeof (struct ah)),
628 ipsec_address(&sav->sah->saidx.dst),
629 (u_long) ntohl(sav->spi)));
630 ahstat.ahs_badauthl++;
631 m_freem(m);
632 return EACCES;
633 }
634 ahstat.ahs_ibytes += m->m_pkthdr.len - skip - hl;
635 DPRINTF(("ah_input skip %d poff %d\n"
636 "len: hl %d authsize %d rpl %d expect %d\n",
637 skip, protoff,
638 hl, authsize, rplen,
639 authsize + rplen - sizeof(struct ah)));
640
641 /* Get crypto descriptors. */
642 crp = crypto_getreq(1);
643 if (crp == NULL) {
644 DPRINTF(("ah_input: failed to acquire crypto descriptor\n"));
645 ahstat.ahs_crypto++;
646 m_freem(m);
647 return ENOBUFS;
648 }
649
650 crda = crp->crp_desc;
651 IPSEC_ASSERT(crda != NULL, ("ah_input: null crypto descriptor"));
652
653 crda->crd_skip = 0;
654 crda->crd_len = m->m_pkthdr.len;
655 crda->crd_inject = skip + rplen;
656
657 /* Authentication operation. */
658 crda->crd_alg = ahx->type;
659 crda->crd_key = _KEYBUF(sav->key_auth);
660 crda->crd_klen = _KEYBITS(sav->key_auth);
661
662 /* Find out if we've already done crypto. */
663 for (mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, NULL);
664 mtag != NULL;
665 mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, mtag)) {
666 tdbi = (struct tdb_ident *) (mtag + 1);
667 if (tdbi->proto == sav->sah->saidx.proto &&
668 tdbi->spi == sav->spi &&
669 !bcmp(&tdbi->dst, &sav->sah->saidx.dst,
670 sizeof (union sockaddr_union)))
671 break;
672 }
673
674 /* Allocate IPsec-specific opaque crypto info. */
675 if (mtag == NULL) {
676 tc = (struct tdb_crypto *) malloc(sizeof (struct tdb_crypto) +
677 skip + rplen + authsize, M_XDATA, M_NOWAIT|M_ZERO);
678 } else {
679 /* Hash verification has already been done successfully. */
680 tc = (struct tdb_crypto *) malloc(sizeof (struct tdb_crypto),
681 M_XDATA, M_NOWAIT|M_ZERO);
682 }
683 if (tc == NULL) {
684 DPRINTF(("ah_input: failed to allocate tdb_crypto\n"));
685 ahstat.ahs_crypto++;
686 crypto_freereq(crp);
687 m_freem(m);
688 return ENOBUFS;
689 }
690
691 /* Only save information if crypto processing is needed. */
692 if (mtag == NULL) {
693 int error;
694
695 /*
696 * Save the authenticator, the skipped portion of the packet,
697 * and the AH header.
698 */
699 m_copydata(m, 0, skip + rplen + authsize, (caddr_t)(tc+1));
700
701 {
702 u_int8_t *pppp = ((caddr_t)(tc+1))+skip+rplen;
703 DPRINTF(("ah_input: zeroing %d bytes of authent " \
704 "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
705 authsize,
706 pppp[0], pppp[1], pppp[2], pppp[3],
707 pppp[4], pppp[5], pppp[6], pppp[7],
708 pppp[8], pppp[9], pppp[10], pppp[11]));
709 }
710
711 /* Zeroize the authenticator on the packet. */
712 m_copyback(m, skip + rplen, authsize, ipseczeroes);
713
714 /* "Massage" the packet headers for crypto processing. */
715 error = ah_massage_headers(&m, sav->sah->saidx.dst.sa.sa_family,
716 skip, ahx->type, 0);
717 if (error != 0) {
718 /* NB: mbuf is free'd by ah_massage_headers */
719 ahstat.ahs_hdrops++;
720 free(tc, M_XDATA);
721 crypto_freereq(crp);
722 return error;
723 }
724 }
725
726 /* Crypto operation descriptor. */
727 crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */
728 crp->crp_flags = CRYPTO_F_IMBUF;
729 crp->crp_buf = (caddr_t) m;
730 crp->crp_callback = ah_input_cb;
731 crp->crp_sid = sav->tdb_cryptoid;
732 crp->crp_opaque = (caddr_t) tc;
733
734 /* These are passed as-is to the callback. */
735 tc->tc_spi = sav->spi;
736 tc->tc_dst = sav->sah->saidx.dst;
737 tc->tc_proto = sav->sah->saidx.proto;
738 tc->tc_nxt = ah->ah_nxt;
739 tc->tc_protoff = protoff;
740 tc->tc_skip = skip;
741 tc->tc_ptr = (caddr_t) mtag; /* Save the mtag we've identified. */
742
743 DPRINTF(("ah: hash over %d bytes, skip %d: "
744 "crda len %d skip %d inject %d\n",
745 crp->crp_ilen, tc->tc_skip,
746 crda->crd_len, crda->crd_skip, crda->crd_inject));
747
748 if (mtag == NULL)
749 return crypto_dispatch(crp);
750 else
751 return ah_input_cb(crp);
752 }
753
754 #ifdef INET6
755 #define IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff, mtag) do { \
756 if (saidx->dst.sa.sa_family == AF_INET6) { \
757 error = ipsec6_common_input_cb(m, sav, skip, protoff, mtag); \
758 } else { \
759 error = ipsec4_common_input_cb(m, sav, skip, protoff, mtag); \
760 } \
761 } while (0)
762 #else
763 #define IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff, mtag) \
764 (error = ipsec4_common_input_cb(m, sav, skip, protoff, mtag))
765 #endif
766
767 /*
768 * AH input callback from the crypto driver.
769 */
770 static int
771 ah_input_cb(struct cryptop *crp)
772 {
773 int rplen, error, skip, protoff;
774 unsigned char calc[AH_ALEN_MAX];
775 struct mbuf *m;
776 struct cryptodesc *crd;
777 struct auth_hash *ahx;
778 struct tdb_crypto *tc;
779 struct m_tag *mtag;
780 struct secasvar *sav;
781 struct secasindex *saidx;
782 u_int8_t nxt;
783 caddr_t ptr;
784 int s, authsize;
785
786 crd = crp->crp_desc;
787
788 tc = (struct tdb_crypto *) crp->crp_opaque;
789 IPSEC_ASSERT(tc != NULL, ("ah_input_cb: null opaque crypto data area!"));
790 skip = tc->tc_skip;
791 nxt = tc->tc_nxt;
792 protoff = tc->tc_protoff;
793 mtag = (struct m_tag *) tc->tc_ptr;
794 m = (struct mbuf *) crp->crp_buf;
795
796 s = splsoftnet();
797
798 sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
799 if (sav == NULL) {
800 ahstat.ahs_notdb++;
801 DPRINTF(("ah_input_cb: SA expired while in crypto\n"));
802 error = ENOBUFS; /*XXX*/
803 goto bad;
804 }
805
806 saidx = &sav->sah->saidx;
807 IPSEC_ASSERT(saidx->dst.sa.sa_family == AF_INET ||
808 saidx->dst.sa.sa_family == AF_INET6,
809 ("ah_input_cb: unexpected protocol family %u",
810 saidx->dst.sa.sa_family));
811
812 ahx = (struct auth_hash *) sav->tdb_authalgxform;
813
814 /* Check for crypto errors. */
815 if (crp->crp_etype) {
816 if (sav->tdb_cryptoid != 0)
817 sav->tdb_cryptoid = crp->crp_sid;
818
819 if (crp->crp_etype == EAGAIN)
820 return crypto_dispatch(crp);
821
822 ahstat.ahs_noxform++;
823 DPRINTF(("ah_input_cb: crypto error %d\n", crp->crp_etype));
824 error = crp->crp_etype;
825 goto bad;
826 } else {
827 ahstat.ahs_hist[sav->alg_auth]++;
828 crypto_freereq(crp); /* No longer needed. */
829 crp = NULL;
830 }
831
832 /* Shouldn't happen... */
833 if (m == NULL) {
834 ahstat.ahs_crypto++;
835 DPRINTF(("ah_input_cb: bogus returned buffer from crypto\n"));
836 error = EINVAL;
837 goto bad;
838 }
839
840 /* Figure out header size. */
841 rplen = HDRSIZE(sav);
842 authsize = AUTHSIZE(sav);
843
844 if (ipsec_debug)
845 bzero(calc, sizeof(calc));
846
847 /* Copy authenticator off the packet. */
848 m_copydata(m, skip + rplen, authsize, calc);
849
850 /*
851 * If we have an mtag, we don't need to verify the authenticator --
852 * it has been verified by an IPsec-aware NIC.
853 */
854 if (mtag == NULL) {
855 ptr = (caddr_t) (tc + 1);
856
857 /* Verify authenticator. */
858 if (bcmp(ptr + skip + rplen, calc, authsize)) {
859 u_int8_t *pppp = ptr + skip+rplen;
860 DPRINTF(("ah_input: authentication hash mismatch " \
861 "over %d bytes " \
862 "for packet in SA %s/%08lx:\n" \
863 "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x, " \
864 "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
865 authsize,
866 ipsec_address(&saidx->dst),
867 (u_long) ntohl(sav->spi),
868 calc[0], calc[1], calc[2], calc[3],
869 calc[4], calc[5], calc[6], calc[7],
870 calc[8], calc[9], calc[10], calc[11],
871 pppp[0], pppp[1], pppp[2], pppp[3],
872 pppp[4], pppp[5], pppp[6], pppp[7],
873 pppp[8], pppp[9], pppp[10], pppp[11]
874 ));
875 ahstat.ahs_badauth++;
876 error = EACCES;
877 goto bad;
878 }
879
880 /* Fix the Next Protocol field. */
881 ((u_int8_t *) ptr)[protoff] = nxt;
882
883 /* Copyback the saved (uncooked) network headers. */
884 m_copyback(m, 0, skip, ptr);
885 } else {
886 /* Fix the Next Protocol field. */
887 m_copyback(m, protoff, sizeof(u_int8_t), &nxt);
888 }
889
890 free(tc, M_XDATA), tc = NULL; /* No longer needed */
891
892 /*
893 * Header is now authenticated.
894 */
895 m->m_flags |= M_AUTHIPHDR|M_AUTHIPDGM;
896
897 /*
898 * Update replay sequence number, if appropriate.
899 */
900 if (sav->replay) {
901 u_int32_t seq;
902
903 m_copydata(m, skip + offsetof(struct newah, ah_seq),
904 sizeof (seq), (caddr_t) &seq);
905 if (ipsec_updatereplay(ntohl(seq), sav)) {
906 ahstat.ahs_replay++;
907 error = ENOBUFS; /*XXX as above*/
908 goto bad;
909 }
910 }
911
912 /*
913 * Remove the AH header and authenticator from the mbuf.
914 */
915 error = m_striphdr(m, skip, rplen + authsize);
916 if (error) {
917 DPRINTF(("ah_input_cb: mangled mbuf chain for SA %s/%08lx\n",
918 ipsec_address(&saidx->dst), (u_long) ntohl(sav->spi)));
919
920 ahstat.ahs_hdrops++;
921 goto bad;
922 }
923
924 IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff, mtag);
925
926 KEY_FREESAV(&sav);
927 splx(s);
928 return error;
929 bad:
930 if (sav)
931 KEY_FREESAV(&sav);
932 splx(s);
933 if (m != NULL)
934 m_freem(m);
935 if (tc != NULL)
936 free(tc, M_XDATA);
937 if (crp != NULL)
938 crypto_freereq(crp);
939 return error;
940 }
941
942 /*
943 * AH output routine, called by ipsec[46]_process_packet().
944 */
945 static int
946 ah_output(
947 struct mbuf *m,
948 struct ipsecrequest *isr,
949 struct mbuf **mp,
950 int skip,
951 int protoff)
952 {
953 struct secasvar *sav;
954 struct auth_hash *ahx;
955 struct cryptodesc *crda;
956 struct tdb_crypto *tc;
957 struct mbuf *mi;
958 struct cryptop *crp;
959 u_int16_t iplen;
960 int error, rplen, authsize, maxpacketsize, roff;
961 u_int8_t prot;
962 struct newah *ah;
963
964 IPSEC_SPLASSERT_SOFTNET("ah_output");
965
966 sav = isr->sav;
967 IPSEC_ASSERT(sav != NULL, ("ah_output: null SA"));
968 ahx = sav->tdb_authalgxform;
969 IPSEC_ASSERT(ahx != NULL, ("ah_output: null authentication xform"));
970
971 ahstat.ahs_output++;
972
973 /* Figure out header size. */
974 rplen = HDRSIZE(sav);
975
976 /* Check for maximum packet size violations. */
977 switch (sav->sah->saidx.dst.sa.sa_family) {
978 #ifdef INET
979 case AF_INET:
980 maxpacketsize = IP_MAXPACKET;
981 break;
982 #endif /* INET */
983 #ifdef INET6
984 case AF_INET6:
985 maxpacketsize = IPV6_MAXPACKET;
986 break;
987 #endif /* INET6 */
988 default:
989 DPRINTF(("ah_output: unknown/unsupported protocol "
990 "family %u, SA %s/%08lx\n",
991 sav->sah->saidx.dst.sa.sa_family,
992 ipsec_address(&sav->sah->saidx.dst),
993 (u_long) ntohl(sav->spi)));
994 ahstat.ahs_nopf++;
995 error = EPFNOSUPPORT;
996 goto bad;
997 }
998 authsize = AUTHSIZE(sav);
999 if (rplen + authsize + m->m_pkthdr.len > maxpacketsize) {
1000 DPRINTF(("ah_output: packet in SA %s/%08lx got too big "
1001 "(len %u, max len %u)\n",
1002 ipsec_address(&sav->sah->saidx.dst),
1003 (u_long) ntohl(sav->spi),
1004 rplen + authsize + m->m_pkthdr.len, maxpacketsize));
1005 ahstat.ahs_toobig++;
1006 error = EMSGSIZE;
1007 goto bad;
1008 }
1009
1010 /* Update the counters. */
1011 ahstat.ahs_obytes += m->m_pkthdr.len - skip;
1012
1013 m = m_clone(m);
1014 if (m == NULL) {
1015 DPRINTF(("ah_output: cannot clone mbuf chain, SA %s/%08lx\n",
1016 ipsec_address(&sav->sah->saidx.dst),
1017 (u_long) ntohl(sav->spi)));
1018 ahstat.ahs_hdrops++;
1019 error = ENOBUFS;
1020 goto bad;
1021 }
1022
1023 /* Inject AH header. */
1024 mi = m_makespace(m, skip, rplen + authsize, &roff);
1025 if (mi == NULL) {
1026 DPRINTF(("ah_output: failed to inject %u byte AH header for SA "
1027 "%s/%08lx\n",
1028 rplen + authsize,
1029 ipsec_address(&sav->sah->saidx.dst),
1030 (u_long) ntohl(sav->spi)));
1031 ahstat.ahs_hdrops++; /*XXX differs from openbsd */
1032 error = ENOBUFS;
1033 goto bad;
1034 }
1035
1036 /*
1037 * The AH header is guaranteed by m_makespace() to be in
1038 * contiguous memory, at roff bytes offset into the returned mbuf.
1039 */
1040 ah = (struct newah *)(mtod(mi, caddr_t) + roff);
1041
1042 /* Initialize the AH header. */
1043 m_copydata(m, protoff, sizeof(u_int8_t), (caddr_t) &ah->ah_nxt);
1044 ah->ah_len = (rplen + authsize - sizeof(struct ah)) / sizeof(u_int32_t);
1045 ah->ah_reserve = 0;
1046 ah->ah_spi = sav->spi;
1047
1048 /* Zeroize authenticator. */
1049 m_copyback(m, skip + rplen, authsize, ipseczeroes);
1050
1051 /* Insert packet replay counter, as requested. */
1052 if (sav->replay) {
1053 if (sav->replay->count == ~0 &&
1054 (sav->flags & SADB_X_EXT_CYCSEQ) == 0) {
1055 DPRINTF(("ah_output: replay counter wrapped for SA "
1056 "%s/%08lx\n",
1057 ipsec_address(&sav->sah->saidx.dst),
1058 (u_long) ntohl(sav->spi)));
1059 ahstat.ahs_wrap++;
1060 error = EINVAL;
1061 goto bad;
1062 }
1063 sav->replay->count++;
1064 ah->ah_seq = htonl(sav->replay->count);
1065 }
1066
1067 /* Get crypto descriptors. */
1068 crp = crypto_getreq(1);
1069 if (crp == NULL) {
1070 DPRINTF(("ah_output: failed to acquire crypto descriptors\n"));
1071 ahstat.ahs_crypto++;
1072 error = ENOBUFS;
1073 goto bad;
1074 }
1075
1076 crda = crp->crp_desc;
1077
1078 crda->crd_skip = 0;
1079 crda->crd_inject = skip + rplen;
1080 crda->crd_len = m->m_pkthdr.len;
1081
1082 /* Authentication operation. */
1083 crda->crd_alg = ahx->type;
1084 crda->crd_key = _KEYBUF(sav->key_auth);
1085 crda->crd_klen = _KEYBITS(sav->key_auth);
1086
1087 /* Allocate IPsec-specific opaque crypto info. */
1088 tc = (struct tdb_crypto *) malloc(
1089 sizeof(struct tdb_crypto) + skip, M_XDATA, M_NOWAIT|M_ZERO);
1090 if (tc == NULL) {
1091 crypto_freereq(crp);
1092 DPRINTF(("ah_output: failed to allocate tdb_crypto\n"));
1093 ahstat.ahs_crypto++;
1094 error = ENOBUFS;
1095 goto bad;
1096 }
1097
1098 /* Save the skipped portion of the packet. */
1099 m_copydata(m, 0, skip, (caddr_t) (tc + 1));
1100
1101 /*
1102 * Fix IP header length on the header used for
1103 * authentication. We don't need to fix the original
1104 * header length as it will be fixed by our caller.
1105 */
1106 switch (sav->sah->saidx.dst.sa.sa_family) {
1107 #ifdef INET
1108 case AF_INET:
1109 bcopy(((caddr_t)(tc + 1)) +
1110 offsetof(struct ip, ip_len),
1111 (caddr_t) &iplen, sizeof(u_int16_t));
1112 iplen = htons(ntohs(iplen) + rplen + authsize);
1113 m_copyback(m, offsetof(struct ip, ip_len),
1114 sizeof(u_int16_t), (caddr_t) &iplen);
1115 break;
1116 #endif /* INET */
1117
1118 #ifdef INET6
1119 case AF_INET6:
1120 bcopy(((caddr_t)(tc + 1)) +
1121 offsetof(struct ip6_hdr, ip6_plen),
1122 (caddr_t) &iplen, sizeof(u_int16_t));
1123 iplen = htons(ntohs(iplen) + rplen + authsize);
1124 m_copyback(m, offsetof(struct ip6_hdr, ip6_plen),
1125 sizeof(u_int16_t), (caddr_t) &iplen);
1126 break;
1127 #endif /* INET6 */
1128 }
1129
1130 /* Fix the Next Header field in saved header. */
1131 ((u_int8_t *) (tc + 1))[protoff] = IPPROTO_AH;
1132
1133 /* Update the Next Protocol field in the IP header. */
1134 prot = IPPROTO_AH;
1135 m_copyback(m, protoff, sizeof(u_int8_t), (caddr_t) &prot);
1136
1137 /* "Massage" the packet headers for crypto processing. */
1138 error = ah_massage_headers(&m, sav->sah->saidx.dst.sa.sa_family,
1139 skip, ahx->type, 1);
1140 if (error != 0) {
1141 m = NULL; /* mbuf was free'd by ah_massage_headers. */
1142 free(tc, M_XDATA);
1143 crypto_freereq(crp);
1144 goto bad;
1145 }
1146
1147 /* Crypto operation descriptor. */
1148 crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */
1149 crp->crp_flags = CRYPTO_F_IMBUF;
1150 crp->crp_buf = (caddr_t) m;
1151 crp->crp_callback = ah_output_cb;
1152 crp->crp_sid = sav->tdb_cryptoid;
1153 crp->crp_opaque = (caddr_t) tc;
1154
1155 /* These are passed as-is to the callback. */
1156 tc->tc_isr = isr;
1157 tc->tc_spi = sav->spi;
1158 tc->tc_dst = sav->sah->saidx.dst;
1159 tc->tc_proto = sav->sah->saidx.proto;
1160 tc->tc_skip = skip;
1161 tc->tc_protoff = protoff;
1162
1163 return crypto_dispatch(crp);
1164 bad:
1165 if (m)
1166 m_freem(m);
1167 return (error);
1168 }
1169
1170 /*
1171 * AH output callback from the crypto driver.
1172 */
1173 static int
1174 ah_output_cb(struct cryptop *crp)
1175 {
1176 int skip, protoff, error;
1177 struct tdb_crypto *tc;
1178 struct ipsecrequest *isr;
1179 struct secasvar *sav;
1180 struct mbuf *m;
1181 caddr_t ptr;
1182 int s, err;
1183
1184 tc = (struct tdb_crypto *) crp->crp_opaque;
1185 IPSEC_ASSERT(tc != NULL, ("ah_output_cb: null opaque data area!"));
1186 skip = tc->tc_skip;
1187 protoff = tc->tc_protoff;
1188 ptr = (caddr_t) (tc + 1);
1189 m = (struct mbuf *) crp->crp_buf;
1190
1191 s = splsoftnet();
1192
1193 isr = tc->tc_isr;
1194 sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
1195 if (sav == NULL) {
1196 ahstat.ahs_notdb++;
1197 DPRINTF(("ah_output_cb: SA expired while in crypto\n"));
1198 error = ENOBUFS; /*XXX*/
1199 goto bad;
1200 }
1201 IPSEC_ASSERT(isr->sav == sav, ("ah_output_cb: SA changed\n"));
1202
1203 /* Check for crypto errors. */
1204 if (crp->crp_etype) {
1205 if (sav->tdb_cryptoid != 0)
1206 sav->tdb_cryptoid = crp->crp_sid;
1207
1208 if (crp->crp_etype == EAGAIN) {
1209 KEY_FREESAV(&sav);
1210 splx(s);
1211 return crypto_dispatch(crp);
1212 }
1213
1214 ahstat.ahs_noxform++;
1215 DPRINTF(("ah_output_cb: crypto error %d\n", crp->crp_etype));
1216 error = crp->crp_etype;
1217 goto bad;
1218 }
1219
1220 /* Shouldn't happen... */
1221 if (m == NULL) {
1222 ahstat.ahs_crypto++;
1223 DPRINTF(("ah_output_cb: bogus returned buffer from crypto\n"));
1224 error = EINVAL;
1225 goto bad;
1226 }
1227 ahstat.ahs_hist[sav->alg_auth]++;
1228
1229 /*
1230 * Copy original headers (with the new protocol number) back
1231 * in place.
1232 */
1233 m_copyback(m, 0, skip, ptr);
1234
1235 /* No longer needed. */
1236 free(tc, M_XDATA);
1237 crypto_freereq(crp);
1238
1239 /* NB: m is reclaimed by ipsec_process_done. */
1240 err = ipsec_process_done(m, isr);
1241 KEY_FREESAV(&sav);
1242 splx(s);
1243 return err;
1244 bad:
1245 if (sav)
1246 KEY_FREESAV(&sav);
1247 splx(s);
1248 if (m)
1249 m_freem(m);
1250 free(tc, M_XDATA);
1251 crypto_freereq(crp);
1252 return error;
1253 }
1254
1255 static struct xformsw ah_xformsw = {
1256 XF_AH, XFT_AUTH, "IPsec AH",
1257 ah_init, ah_zeroize, ah_input, ah_output,
1258 };
1259
1260 INITFN void
1261 ah_attach(void)
1262 {
1263 xform_register(&ah_xformsw);
1264 }
1265
1266 #ifdef __FreeBSD__
1267 SYSINIT(ah_xform_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE, ah_attach, NULL);
1268 #endif
1269