1 /* $OpenBSD: ip_ah.c,v 1.79 2003/08/14 19:00:12 jason 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 <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/mbuf.h>
42 #include <sys/socket.h>
43
44 #include <net/if.h>
45 #include <net/bpf.h>
46
47 #ifdef INET
48 #include <netinet/in.h>
49 #include <netinet/in_systm.h>
50 #include <netinet/ip.h>
51 #endif /* INET */
52
53 #ifdef INET6
54 #ifndef INET
55 #include <netinet/in.h>
56 #endif /* INET */
57 #include <netinet/ip6.h>
58 #endif /* INET6 */
59
60 #include <netinet/ip_ipsp.h>
61 #include <netinet/ip_ah.h>
62 #include <net/pfkeyv2.h>
63 #include <net/if_enc.h>
64
65 #include <crypto/cryptodev.h>
66 #include <crypto/xform.h>
67
68 #include "bpfilter.h"
69
70 #ifdef ENCDEBUG
71 #define DPRINTF(x) if (encdebug) printf x
72 #else
73 #define DPRINTF(x)
74 #endif
75
76 struct ahstat ahstat;
77
78 /*
79 * ah_attach() is called from the transformation initialization code.
80 */
81 int
ah_attach()82 ah_attach()
83 {
84 return 0;
85 }
86
87 /*
88 * ah_init() is called when an SPI is being set up.
89 */
90 int
ah_init(struct tdb * tdbp,struct xformsw * xsp,struct ipsecinit * ii)91 ah_init(struct tdb *tdbp, struct xformsw *xsp, struct ipsecinit *ii)
92 {
93 struct auth_hash *thash = NULL;
94 struct cryptoini cria;
95
96 /* Authentication operation. */
97 switch (ii->ii_authalg) {
98 case SADB_AALG_MD5HMAC:
99 thash = &auth_hash_hmac_md5_96;
100 break;
101
102 case SADB_AALG_SHA1HMAC:
103 thash = &auth_hash_hmac_sha1_96;
104 break;
105
106 case SADB_X_AALG_RIPEMD160HMAC:
107 thash = &auth_hash_hmac_ripemd_160_96;
108 break;
109
110 case SADB_X_AALG_SHA2_256:
111 thash = &auth_hash_hmac_sha2_256_96;
112 break;
113
114 case SADB_X_AALG_SHA2_384:
115 thash = &auth_hash_hmac_sha2_384_96;
116 break;
117
118 case SADB_X_AALG_SHA2_512:
119 thash = &auth_hash_hmac_sha2_512_96;
120 break;
121
122 case SADB_X_AALG_MD5:
123 thash = &auth_hash_key_md5;
124 break;
125
126 case SADB_X_AALG_SHA1:
127 thash = &auth_hash_key_sha1;
128 break;
129
130 default:
131 DPRINTF(("ah_init(): unsupported authentication algorithm %d specified\n", ii->ii_authalg));
132 return EINVAL;
133 }
134
135 if (ii->ii_authkeylen != thash->keysize && thash->keysize != 0) {
136 DPRINTF(("ah_init(): keylength %d doesn't match algorithm "
137 "%s keysize (%d)\n", ii->ii_authkeylen, thash->name,
138 thash->keysize));
139 return EINVAL;
140 }
141
142 tdbp->tdb_xform = xsp;
143 tdbp->tdb_authalgxform = thash;
144 tdbp->tdb_bitmap = 0;
145 tdbp->tdb_rpl = AH_HMAC_INITIAL_RPL;
146
147 DPRINTF(("ah_init(): initialized TDB with hash algorithm %s\n",
148 thash->name));
149
150 tdbp->tdb_amxkeylen = ii->ii_authkeylen;
151 MALLOC(tdbp->tdb_amxkey, u_int8_t *, tdbp->tdb_amxkeylen, M_XDATA,
152 M_WAITOK);
153
154 bcopy(ii->ii_authkey, tdbp->tdb_amxkey, tdbp->tdb_amxkeylen);
155
156 /* Initialize crypto session. */
157 bzero(&cria, sizeof(cria));
158 cria.cri_alg = tdbp->tdb_authalgxform->type;
159 cria.cri_klen = ii->ii_authkeylen * 8;
160 cria.cri_key = ii->ii_authkey;
161
162 return crypto_newsession(&tdbp->tdb_cryptoid, &cria, 0);
163 }
164
165 /*
166 * Paranoia.
167 */
168 int
ah_zeroize(struct tdb * tdbp)169 ah_zeroize(struct tdb *tdbp)
170 {
171 int err;
172
173 if (tdbp->tdb_amxkey) {
174 bzero(tdbp->tdb_amxkey, tdbp->tdb_amxkeylen);
175 FREE(tdbp->tdb_amxkey, M_XDATA);
176 tdbp->tdb_amxkey = NULL;
177 }
178
179 err = crypto_freesession(tdbp->tdb_cryptoid);
180 tdbp->tdb_cryptoid = 0;
181 return err;
182 }
183
184 /*
185 * Massage IPv4/IPv6 headers for AH processing.
186 */
187 int
ah_massage_headers(struct mbuf ** m0,int proto,int skip,int alg,int out)188 ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
189 {
190 struct mbuf *m = *m0;
191 unsigned char *ptr;
192 int off, count;
193
194 #ifdef INET
195 struct ip *ip;
196 #endif /* INET */
197
198 #ifdef INET6
199 struct ip6_ext *ip6e;
200 struct ip6_hdr ip6;
201 int alloc, len, ad;
202 #endif /* INET6 */
203
204 switch (proto) {
205 #ifdef INET
206 case AF_INET:
207 /*
208 * This is the least painful way of dealing with IPv4 header
209 * and option processing -- just make sure they're in
210 * contiguous memory.
211 */
212 *m0 = m = m_pullup(m, skip);
213 if (m == NULL) {
214 DPRINTF(("ah_massage_headers(): m_pullup() failed\n"));
215 ahstat.ahs_hdrops++;
216 return ENOBUFS;
217 }
218
219 /* Fix the IP header */
220 ip = mtod(m, struct ip *);
221 ip->ip_tos = 0;
222 ip->ip_ttl = 0;
223 ip->ip_sum = 0;
224
225 /*
226 * On input, fix ip_len which has been byte-swapped
227 * at ip_input().
228 */
229 if (alg == CRYPTO_MD5_KPDK || alg == CRYPTO_SHA1_KPDK)
230 ip->ip_off &= htons(IP_DF);
231 else
232 ip->ip_off = 0;
233
234 ptr = mtod(m, unsigned char *) + sizeof(struct ip);
235
236 /* IPv4 option processing */
237 for (off = sizeof(struct ip); off < skip;) {
238 if (ptr[off] == IPOPT_EOL || ptr[off] == IPOPT_NOP ||
239 off + 1 < skip)
240 ;
241 else {
242 DPRINTF(("ah_massage_headers(): illegal IPv4 "
243 "option length for option %d\n",
244 ptr[off]));
245
246 ahstat.ahs_hdrops++;
247 m_freem(m);
248 return EINVAL;
249 }
250
251 switch (ptr[off]) {
252 case IPOPT_EOL:
253 off = skip; /* End the loop. */
254 break;
255
256 case IPOPT_NOP:
257 off++;
258 break;
259
260 case IPOPT_SECURITY: /* 0x82 */
261 case 0x85: /* Extended security. */
262 case 0x86: /* Commercial security. */
263 case 0x94: /* Router alert */
264 case 0x95: /* RFC1770 */
265 /* Sanity check for option length. */
266 if (ptr[off + 1] < 2) {
267 DPRINTF(("ah_massage_headers(): "
268 "illegal IPv4 option length for "
269 "option %d\n", ptr[off]));
270
271 ahstat.ahs_hdrops++;
272 m_freem(m);
273 return EINVAL;
274 }
275
276 off += ptr[off + 1];
277 break;
278
279 case IPOPT_LSRR:
280 case IPOPT_SSRR:
281 /* Sanity check for option length. */
282 if (ptr[off + 1] < 2) {
283 DPRINTF(("ah_massage_headers(): "
284 "illegal IPv4 option length for "
285 "option %d\n", ptr[off]));
286
287 ahstat.ahs_hdrops++;
288 m_freem(m);
289 return EINVAL;
290 }
291
292 /*
293 * On output, if we have either of the
294 * source routing options, we should
295 * swap the destination address of the
296 * IP header with the last address
297 * specified in the option, as that is
298 * what the destination's IP header
299 * will look like.
300 */
301 if (out)
302 bcopy(ptr + off + ptr[off + 1] -
303 sizeof(struct in_addr),
304 &(ip->ip_dst), sizeof(struct in_addr));
305
306 /* Fall through */
307 default:
308 /* Sanity check for option length. */
309 if (ptr[off + 1] < 2) {
310 DPRINTF(("ah_massage_headers(): "
311 "illegal IPv4 option length for "
312 "option %d\n", ptr[off]));
313 ahstat.ahs_hdrops++;
314 m_freem(m);
315 return EINVAL;
316 }
317
318 /* Zeroize all other options. */
319 count = ptr[off + 1];
320 bcopy(ipseczeroes, ptr, count);
321 off += count;
322 break;
323 }
324
325 /* Sanity check. */
326 if (off > skip) {
327 DPRINTF(("ah_massage_headers(): malformed "
328 "IPv4 options header\n"));
329
330 ahstat.ahs_hdrops++;
331 m_freem(m);
332 return EINVAL;
333 }
334 }
335
336 break;
337 #endif /* INET */
338
339 #ifdef INET6
340 case AF_INET6: /* Ugly... */
341 /* Copy and "cook" the IPv6 header. */
342 m_copydata(m, 0, sizeof(ip6), (caddr_t) &ip6);
343
344 /* We don't do IPv6 Jumbograms. */
345 if (ip6.ip6_plen == 0) {
346 DPRINTF(("ah_massage_headers(): unsupported IPv6 "
347 "jumbogram"));
348 ahstat.ahs_hdrops++;
349 m_freem(m);
350 return EMSGSIZE;
351 }
352
353 ip6.ip6_flow = 0;
354 ip6.ip6_hlim = 0;
355 ip6.ip6_vfc &= ~IPV6_VERSION_MASK;
356 ip6.ip6_vfc |= IPV6_VERSION;
357
358 /* Scoped address handling. */
359 if (IN6_IS_SCOPE_LINKLOCAL(&ip6.ip6_src))
360 ip6.ip6_src.s6_addr16[1] = 0;
361 if (IN6_IS_SCOPE_LINKLOCAL(&ip6.ip6_dst))
362 ip6.ip6_dst.s6_addr16[1] = 0;
363
364 /* Done with IPv6 header. */
365 m_copyback(m, 0, sizeof(struct ip6_hdr), &ip6);
366
367 /* Let's deal with the remaining headers (if any). */
368 if (skip - sizeof(struct ip6_hdr) > 0) {
369 if (m->m_len <= skip) {
370 MALLOC(ptr, unsigned char *,
371 skip - sizeof(struct ip6_hdr),
372 M_XDATA, M_NOWAIT);
373 if (ptr == NULL) {
374 DPRINTF(("ah_massage_headers(): failed to allocate memory for IPv6 headers\n"));
375 ahstat.ahs_hdrops++;
376 m_freem(m);
377 return ENOBUFS;
378 }
379
380 /*
381 * Copy all the protocol headers after
382 * the IPv6 header.
383 */
384 m_copydata(m, sizeof(struct ip6_hdr),
385 skip - sizeof(struct ip6_hdr), ptr);
386 alloc = 1;
387 } else {
388 /* No need to allocate memory. */
389 ptr = mtod(m, unsigned char *) +
390 sizeof(struct ip6_hdr);
391 alloc = 0;
392 }
393 } else
394 break;
395
396 off = ip6.ip6_nxt & 0xff; /* Next header type. */
397
398 for (len = 0; len < skip - sizeof(struct ip6_hdr);)
399 switch (off) {
400 case IPPROTO_HOPOPTS:
401 case IPPROTO_DSTOPTS:
402 ip6e = (struct ip6_ext *) (ptr + len);
403
404 /*
405 * Process the mutable/immutable
406 * options -- borrows heavily from the
407 * KAME code.
408 */
409 for (count = len + sizeof(struct ip6_ext);
410 count < len + ((ip6e->ip6e_len + 1) << 3);) {
411 if (ptr[count] == IP6OPT_PAD1) {
412 count++;
413 continue; /* Skip padding. */
414 }
415
416 /* Sanity check. */
417 if (count > len +
418 ((ip6e->ip6e_len + 1) << 3)) {
419 ahstat.ahs_hdrops++;
420 m_freem(m);
421
422 /* Free, if we allocated. */
423 if (alloc)
424 FREE(ptr, M_XDATA);
425 return EINVAL;
426 }
427
428 ad = ptr[count + 1];
429
430 /* If mutable option, zeroize. */
431 if (ptr[count] & IP6OPT_MUTABLE)
432 bcopy(ipseczeroes, ptr + count,
433 ptr[count + 1]);
434
435 count += ad;
436
437 /* Sanity check. */
438 if (count >
439 skip - sizeof(struct ip6_hdr)) {
440 ahstat.ahs_hdrops++;
441 m_freem(m);
442
443 /* Free, if we allocated. */
444 if (alloc)
445 FREE(ptr, M_XDATA);
446 return EINVAL;
447 }
448 }
449
450 /* Advance. */
451 len += ((ip6e->ip6e_len + 1) << 3);
452 off = ip6e->ip6e_nxt;
453 break;
454
455 case IPPROTO_ROUTING:
456 /*
457 * Always include routing headers in
458 * computation.
459 */
460 ip6e = (struct ip6_ext *) (ptr + len);
461 len += ((ip6e->ip6e_len + 1) << 3);
462 off = ip6e->ip6e_nxt;
463 break;
464
465 default:
466 DPRINTF(("ah_massage_headers(): unexpected "
467 "IPv6 header type %d\n", off));
468 if (alloc)
469 FREE(ptr, M_XDATA);
470 ahstat.ahs_hdrops++;
471 m_freem(m);
472 return EINVAL;
473 }
474
475 /* Copyback and free, if we allocated. */
476 if (alloc) {
477 m_copyback(m, sizeof(struct ip6_hdr),
478 skip - sizeof(struct ip6_hdr), ptr);
479 FREE(ptr, M_XDATA);
480 }
481
482 break;
483 #endif /* INET6 */
484 }
485
486 return 0;
487 }
488
489 /*
490 * ah_input() gets called to verify that an input packet
491 * passes authentication.
492 */
493 int
ah_input(struct mbuf * m,struct tdb * tdb,int skip,int protoff)494 ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
495 {
496 struct auth_hash *ahx = (struct auth_hash *) tdb->tdb_authalgxform;
497 struct tdb_ident *tdbi;
498 struct tdb_crypto *tc;
499 struct m_tag *mtag;
500 u_int32_t btsx;
501 u_int8_t hl;
502 int rplen;
503
504 struct cryptodesc *crda = NULL;
505 struct cryptop *crp;
506
507 if (!(tdb->tdb_flags & TDBF_NOREPLAY))
508 rplen = AH_FLENGTH + sizeof(u_int32_t);
509 else
510 rplen = AH_FLENGTH;
511
512 /* Save the AH header, we use it throughout. */
513 m_copydata(m, skip + offsetof(struct ah, ah_hl), sizeof(u_int8_t),
514 (caddr_t) &hl);
515
516 /* Replay window checking, if applicable. */
517 if ((tdb->tdb_wnd > 0) && (!(tdb->tdb_flags & TDBF_NOREPLAY))) {
518 m_copydata(m, skip + offsetof(struct ah, ah_rpl),
519 sizeof(u_int32_t), (caddr_t) &btsx);
520 btsx = ntohl(btsx);
521
522 switch (checkreplaywindow32(btsx, 0, &(tdb->tdb_rpl),
523 tdb->tdb_wnd, &(tdb->tdb_bitmap), 0)) {
524 case 0: /* All's well. */
525 break;
526
527 case 1:
528 DPRINTF(("ah_input(): replay counter wrapped for "
529 "SA %s/%08x\n", ipsp_address(tdb->tdb_dst),
530 ntohl(tdb->tdb_spi)));
531
532 ahstat.ahs_wrap++;
533 m_freem(m);
534 return ENOBUFS;
535
536 case 2:
537 case 3:
538 DPRINTF(("ah_input(): duplicate packet received in "
539 "SA %s/%08x\n", ipsp_address(tdb->tdb_dst),
540 ntohl(tdb->tdb_spi)));
541
542 m_freem(m);
543 return ENOBUFS;
544
545 default:
546 DPRINTF(("ah_input(): bogus value from "
547 "checkreplaywindow32() in SA %s/%08x\n",
548 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
549
550 ahstat.ahs_replay++;
551 m_freem(m);
552 return ENOBUFS;
553 }
554 }
555
556 /* Verify AH header length. */
557 if (hl * sizeof(u_int32_t) != ahx->authsize + rplen - AH_FLENGTH) {
558 DPRINTF(("ah_input(): bad authenticator length %d for packet "
559 "in SA %s/%08x\n", hl * sizeof(u_int32_t),
560 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
561
562 ahstat.ahs_badauthl++;
563 m_freem(m);
564 return EACCES;
565 }
566
567 /* Update the counters. */
568 tdb->tdb_cur_bytes +=
569 (m->m_pkthdr.len - skip - hl * sizeof(u_int32_t));
570 ahstat.ahs_ibytes += (m->m_pkthdr.len - skip - hl * sizeof(u_int32_t));
571
572 /* Hard expiration. */
573 if (tdb->tdb_flags & TDBF_BYTES &&
574 tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) {
575 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
576 tdb_delete(tdb);
577 m_freem(m);
578 return ENXIO;
579 }
580
581 /* Notify on expiration. */
582 if (tdb->tdb_flags & TDBF_SOFT_BYTES &&
583 tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) {
584 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
585 tdb->tdb_flags &= ~TDBF_SOFT_BYTES; /* Turn off checking. */
586 }
587
588 /* Get crypto descriptors. */
589 crp = crypto_getreq(1);
590 if (crp == NULL) {
591 m_freem(m);
592 DPRINTF(("ah_input(): failed to acquire crypto "
593 "descriptors\n"));
594 ahstat.ahs_crypto++;
595 return ENOBUFS;
596 }
597
598 crda = crp->crp_desc;
599
600 crda->crd_skip = 0;
601 crda->crd_len = m->m_pkthdr.len;
602 crda->crd_inject = skip + rplen;
603
604 /* Authentication operation. */
605 crda->crd_alg = ahx->type;
606 crda->crd_key = tdb->tdb_amxkey;
607 crda->crd_klen = tdb->tdb_amxkeylen * 8;
608
609 /* Find out if we've already done crypto. */
610 for (mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, NULL);
611 mtag != NULL;
612 mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, mtag)) {
613 tdbi = (struct tdb_ident *) (mtag + 1);
614 if (tdbi->proto == tdb->tdb_sproto &&
615 tdbi->spi == tdb->tdb_spi &&
616 !bcmp(&tdbi->dst, &tdb->tdb_dst,
617 sizeof(union sockaddr_union)))
618 break;
619 }
620
621 /* Allocate IPsec-specific opaque crypto info. */
622 if (mtag == NULL)
623 MALLOC(tc, struct tdb_crypto *,
624 sizeof(struct tdb_crypto) + skip +
625 rplen + ahx->authsize, M_XDATA, M_NOWAIT);
626 else /* Hash verification has already been done successfully. */
627 MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto),
628 M_XDATA, M_NOWAIT);
629 if (tc == NULL) {
630 m_freem(m);
631 crypto_freereq(crp);
632 DPRINTF(("ah_input(): failed to allocate tdb_crypto\n"));
633 ahstat.ahs_crypto++;
634 return ENOBUFS;
635 }
636
637 bzero(tc, sizeof(struct tdb_crypto));
638
639 /* Only save information if crypto processing is needed. */
640 if (mtag == NULL) {
641 /*
642 * Save the authenticator, the skipped portion of the packet,
643 * and the AH header.
644 */
645 m_copydata(m, 0, skip + rplen + ahx->authsize,
646 (caddr_t) (tc + 1));
647
648 /* Zeroize the authenticator on the packet. */
649 m_copyback(m, skip + rplen, ahx->authsize, ipseczeroes);
650
651 /* "Massage" the packet headers for crypto processing. */
652 if ((btsx = ah_massage_headers(&m, tdb->tdb_dst.sa.sa_family,
653 skip, ahx->type, 0)) != 0) {
654 /* mbuf will be free'd by callee. */
655 FREE(tc, M_XDATA);
656 crypto_freereq(crp);
657 return btsx;
658 }
659 }
660
661 /* Crypto operation descriptor. */
662 crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */
663 crp->crp_flags = CRYPTO_F_IMBUF;
664 crp->crp_buf = (caddr_t) m;
665 crp->crp_callback = (int (*) (struct cryptop *)) ah_input_cb;
666 crp->crp_sid = tdb->tdb_cryptoid;
667 crp->crp_opaque = (caddr_t) tc;
668
669 /* These are passed as-is to the callback. */
670 tc->tc_skip = skip;
671 tc->tc_protoff = protoff;
672 tc->tc_spi = tdb->tdb_spi;
673 tc->tc_proto = tdb->tdb_sproto;
674 tc->tc_ptr = (caddr_t) mtag; /* Save the mtag we've identified. */
675 bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
676
677 if (mtag == NULL)
678 return crypto_dispatch(crp);
679 else
680 return ah_input_cb(crp);
681 }
682
683 /*
684 * AH input callback, called directly by the crypto driver.
685 */
686 int
ah_input_cb(void * op)687 ah_input_cb(void *op)
688 {
689 int s, roff, rplen, error = 0, skip, protoff;
690 unsigned char calc[AH_ALEN_MAX];
691 struct mbuf *m1, *m0, *m;
692 struct cryptodesc *crd;
693 struct auth_hash *ahx;
694 struct tdb_crypto *tc;
695 struct cryptop *crp;
696 struct m_tag *mtag;
697 struct tdb *tdb;
698 u_int32_t btsx;
699 u_int8_t prot;
700 caddr_t ptr;
701
702 crp = (struct cryptop *) op;
703 crd = crp->crp_desc;
704
705 tc = (struct tdb_crypto *) crp->crp_opaque;
706 skip = tc->tc_skip;
707 protoff = tc->tc_protoff;
708 mtag = (struct m_tag *) tc->tc_ptr;
709
710 m = (struct mbuf *) crp->crp_buf;
711 if (m == NULL) {
712 /* Shouldn't happen... */
713 FREE(tc, M_XDATA);
714 crypto_freereq(crp);
715 ahstat.ahs_crypto++;
716 DPRINTF(("ah_input_cb(): bogus returned buffer from "
717 "crypto\n"));
718 return (EINVAL);
719 }
720
721 s = spltdb();
722
723 tdb = gettdb(tc->tc_spi, &tc->tc_dst, tc->tc_proto);
724 if (tdb == NULL) {
725 FREE(tc, M_XDATA);
726 ahstat.ahs_notdb++;
727 DPRINTF(("ah_input_cb(): TDB is expired while in crypto"));
728 error = EPERM;
729 goto baddone;
730 }
731
732 ahx = (struct auth_hash *) tdb->tdb_authalgxform;
733
734 /* Check for crypto errors. */
735 if (crp->crp_etype) {
736 if (crp->crp_etype == EAGAIN) {
737 /* Reset the session ID */
738 if (tdb->tdb_cryptoid != 0)
739 tdb->tdb_cryptoid = crp->crp_sid;
740 splx(s);
741 return crypto_dispatch(crp);
742 }
743 FREE(tc, M_XDATA);
744 ahstat.ahs_noxform++;
745 DPRINTF(("ah_input_cb(): crypto error %d\n", crp->crp_etype));
746 error = crp->crp_etype;
747 goto baddone;
748 } else {
749 crypto_freereq(crp); /* No longer needed. */
750 crp = NULL;
751 }
752
753 if (!(tdb->tdb_flags & TDBF_NOREPLAY))
754 rplen = AH_FLENGTH + sizeof(u_int32_t);
755 else
756 rplen = AH_FLENGTH;
757
758 /* Copy authenticator off the packet. */
759 m_copydata(m, skip + rplen, ahx->authsize, calc);
760
761 /*
762 * If we have an mtag, we don't need to verify the authenticator --
763 * it has been verified by an IPsec-aware NIC.
764 */
765 if (mtag == NULL) {
766 ptr = (caddr_t) (tc + 1);
767
768 /* Verify authenticator. */
769 if (bcmp(ptr + skip + rplen, calc, ahx->authsize)) {
770 FREE(tc, M_XDATA);
771
772 DPRINTF(("ah_input(): authentication failed for "
773 "packet in SA %s/%08x\n",
774 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
775
776 ahstat.ahs_badauth++;
777 error = EACCES;
778 goto baddone;
779 }
780
781 /* Fix the Next Protocol field. */
782 ((u_int8_t *) ptr)[protoff] = ((u_int8_t *) ptr)[skip];
783
784 /* Copyback the saved (uncooked) network headers. */
785 m_copyback(m, 0, skip, ptr);
786 } else {
787 /* Fix the Next Protocol field. */
788 m_copydata(m, skip, sizeof(u_int8_t), &prot);
789 m_copyback(m, protoff, sizeof(u_int8_t), &prot);
790 }
791
792 FREE(tc, M_XDATA);
793
794 /* Replay window checking, if applicable. */
795 if ((tdb->tdb_wnd > 0) && (!(tdb->tdb_flags & TDBF_NOREPLAY))) {
796 m_copydata(m, skip + offsetof(struct ah, ah_rpl),
797 sizeof(u_int32_t), (caddr_t) &btsx);
798 btsx = ntohl(btsx);
799
800 switch (checkreplaywindow32(btsx, 0, &(tdb->tdb_rpl),
801 tdb->tdb_wnd, &(tdb->tdb_bitmap), 1)) {
802 case 0: /* All's well. */
803 break;
804
805 case 1:
806 DPRINTF(("ah_input(): replay counter wrapped for "
807 "SA %s/%08x\n", ipsp_address(tdb->tdb_dst),
808 ntohl(tdb->tdb_spi)));
809
810 ahstat.ahs_wrap++;
811 error = ENOBUFS;
812 goto baddone;
813
814 case 2:
815 case 3:
816 DPRINTF(("ah_input_cb(): duplicate packet received in "
817 "SA %s/%08x\n", ipsp_address(tdb->tdb_dst),
818 ntohl(tdb->tdb_spi)));
819
820 error = ENOBUFS;
821 goto baddone;
822
823 default:
824 DPRINTF(("ah_input_cb(): bogus value from "
825 "checkreplaywindow32() in SA %s/%08x\n",
826 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
827
828 ahstat.ahs_replay++;
829 error = ENOBUFS;
830 goto baddone;
831 }
832 }
833
834 /* Record the beginning of the AH header. */
835 m1 = m_getptr(m, skip, &roff);
836 if (m1 == NULL) {
837 ahstat.ahs_hdrops++;
838 splx(s);
839 m_freem(m);
840
841 DPRINTF(("ah_input(): bad mbuf chain for packet in SA "
842 "%s/%08x\n", ipsp_address(tdb->tdb_dst),
843 ntohl(tdb->tdb_spi)));
844
845 return EINVAL;
846 }
847
848 /* Remove the AH header from the mbuf. */
849 if (roff == 0) {
850 /*
851 * The AH header was conveniently at the beginning of
852 * the mbuf.
853 */
854 m_adj(m1, rplen + ahx->authsize);
855 if (!(m1->m_flags & M_PKTHDR))
856 m->m_pkthdr.len -= rplen + ahx->authsize;
857 } else
858 if (roff + rplen + ahx->authsize >= m1->m_len) {
859 /*
860 * Part or all of the AH header is at the end
861 * of this mbuf, so first let's remove the
862 * remainder of the AH header from the
863 * beginning of the remainder of the mbuf
864 * chain, if any.
865 */
866 if (roff + rplen + ahx->authsize > m1->m_len) {
867 /* Adjust the next mbuf by the remainder. */
868 m_adj(m1->m_next, roff + rplen +
869 ahx->authsize - m1->m_len);
870
871 /*
872 * The second mbuf is guaranteed not
873 * to have a pkthdr...
874 */
875 m->m_pkthdr.len -=
876 (roff + rplen + ahx->authsize - m1->m_len);
877 }
878
879 /* Now, let's unlink the mbuf chain for a second... */
880 m0 = m1->m_next;
881 m1->m_next = NULL;
882
883 /*
884 * ...and trim the end of the first part of
885 * the chain...sick
886 */
887 m_adj(m1, -(m1->m_len - roff));
888 if (!(m1->m_flags & M_PKTHDR))
889 m->m_pkthdr.len -= (m1->m_len - roff);
890
891 /* Finally, let's relink. */
892 m1->m_next = m0;
893 } else {
894 /*
895 * The AH header lies in the "middle" of the
896 * mbuf...do an overlapping copy of the
897 * remainder of the mbuf over the ESP header.
898 */
899 bcopy(mtod(m1, u_char *) + roff + rplen +
900 ahx->authsize, mtod(m1, u_char *) + roff,
901 m1->m_len - (roff + rplen + ahx->authsize));
902 m1->m_len -= rplen + ahx->authsize;
903 m->m_pkthdr.len -= rplen + ahx->authsize;
904 }
905
906 error = ipsec_common_input_cb(m, tdb, skip, protoff, mtag);
907 splx(s);
908 return (error);
909
910 baddone:
911 splx(s);
912
913 if (m != NULL)
914 m_freem(m);
915
916 if (crp != NULL)
917 crypto_freereq(crp);
918
919 return (error);
920 }
921
922 /*
923 * AH output routine, called by ipsp_process_packet().
924 */
925 int
ah_output(struct mbuf * m,struct tdb * tdb,struct mbuf ** mp,int skip,int protoff)926 ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
927 int protoff)
928 {
929 struct auth_hash *ahx = (struct auth_hash *) tdb->tdb_authalgxform;
930 struct cryptodesc *crda;
931 struct tdb_crypto *tc;
932 struct mbuf *mo, *mi;
933 struct cryptop *crp;
934 u_int16_t iplen;
935 int len, rplen;
936 u_int8_t prot;
937 struct ah *ah;
938
939 #if NBPFILTER > 0
940 {
941 struct ifnet *ifn;
942 struct enchdr hdr;
943 struct mbuf m1;
944
945 bzero (&hdr, sizeof(hdr));
946
947 hdr.af = tdb->tdb_dst.sa.sa_family;
948 hdr.spi = tdb->tdb_spi;
949 hdr.flags |= M_AUTH | M_AUTH_AH;
950
951 m1.m_flags = 0;
952 m1.m_next = m;
953 m1.m_len = ENC_HDRLEN;
954 m1.m_data = (char *) &hdr;
955
956 ifn = &(encif[0].sc_if);
957
958 if (ifn->if_bpf)
959 bpf_mtap(ifn->if_bpf, &m1);
960 }
961 #endif
962
963 ahstat.ahs_output++;
964
965 /*
966 * Check for replay counter wrap-around in automatic (not
967 * manual) keying.
968 */
969 if ((tdb->tdb_rpl == 0) && (tdb->tdb_wnd > 0) &&
970 (!(tdb->tdb_flags & TDBF_NOREPLAY))) {
971 DPRINTF(("ah_output(): SA %s/%08x should have expired\n",
972 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
973 m_freem(m);
974 ahstat.ahs_wrap++;
975 return EINVAL;
976 }
977
978 if (!(tdb->tdb_flags & TDBF_NOREPLAY))
979 rplen = AH_FLENGTH + sizeof(u_int32_t);
980 else
981 rplen = AH_FLENGTH;
982
983 switch (tdb->tdb_dst.sa.sa_family) {
984 #ifdef INET
985 case AF_INET:
986 /* Check for IP maximum packet size violations. */
987 if (rplen + ahx->authsize + m->m_pkthdr.len > IP_MAXPACKET) {
988 DPRINTF(("ah_output(): packet in SA %s/%08x got too "
989 "big\n",
990 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
991 m_freem(m);
992 ahstat.ahs_toobig++;
993 return EMSGSIZE;
994 }
995 break;
996 #endif /* INET */
997
998 #ifdef INET6
999 case AF_INET6:
1000 /* Check for IPv6 maximum packet size violations. */
1001 if (rplen + ahx->authsize + m->m_pkthdr.len > IPV6_MAXPACKET) {
1002 DPRINTF(("ah_output(): packet in SA %s/%08x "
1003 "got too big\n", ipsp_address(tdb->tdb_dst),
1004 ntohl(tdb->tdb_spi)));
1005 m_freem(m);
1006 ahstat.ahs_toobig++;
1007 return EMSGSIZE;
1008 }
1009 break;
1010 #endif /* INET6 */
1011
1012 default:
1013 DPRINTF(("ah_output(): unknown/unsupported protocol "
1014 "family %d, SA %s/%08x\n", tdb->tdb_dst.sa.sa_family,
1015 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
1016 m_freem(m);
1017 ahstat.ahs_nopf++;
1018 return EPFNOSUPPORT;
1019 }
1020
1021 /* Update the counters. */
1022 tdb->tdb_cur_bytes += m->m_pkthdr.len - skip;
1023 ahstat.ahs_obytes += m->m_pkthdr.len - skip;
1024
1025 /* Hard expiration. */
1026 if (tdb->tdb_flags & TDBF_BYTES &&
1027 tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) {
1028 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
1029 tdb_delete(tdb);
1030 m_freem(m);
1031 return EINVAL;
1032 }
1033
1034 /* Notify on expiration. */
1035 if (tdb->tdb_flags & TDBF_SOFT_BYTES &&
1036 tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) {
1037 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
1038 tdb->tdb_flags &= ~TDBF_SOFT_BYTES; /* Turn off checking */
1039 }
1040
1041 /*
1042 * Loop through mbuf chain; if we find an M_EXT mbuf with
1043 * more than one reference, replace the rest of the chain.
1044 */
1045 mo = NULL;
1046 mi = m;
1047 while (mi != NULL &&
1048 (!(mi->m_flags & M_EXT) || !MCLISREFERENCED(mi))) {
1049 mo = mi;
1050 mi = mi->m_next;
1051 }
1052
1053 if (mi != NULL) {
1054 /* Replace the rest of the mbuf chain. */
1055 struct mbuf *n = m_copym2(mi, 0, M_COPYALL, M_DONTWAIT);
1056
1057 if (n == NULL) {
1058 ahstat.ahs_hdrops++;
1059 m_freem(m);
1060 return ENOBUFS;
1061 }
1062
1063 if (mo != NULL)
1064 mo->m_next = n;
1065 else
1066 m = n;
1067
1068 m_freem(mi);
1069 }
1070
1071 /* Inject AH header. */
1072 mi = m_inject(m, skip, rplen + ahx->authsize, M_DONTWAIT);
1073 if (mi == NULL) {
1074 DPRINTF(("ah_output(): failed to inject AH header for SA "
1075 "%s/%08x\n", ipsp_address(tdb->tdb_dst),
1076 ntohl(tdb->tdb_spi)));
1077
1078 m_freem(m);
1079 ahstat.ahs_hdrops++;
1080 return ENOBUFS;
1081 }
1082
1083 /*
1084 * The AH header is guaranteed by m_inject() to be in
1085 * contiguous memory, at the beginning of the returned mbuf.
1086 */
1087 ah = mtod(mi, struct ah *);
1088
1089 /* Initialize the AH header. */
1090 m_copydata(m, protoff, sizeof(u_int8_t), (caddr_t) &ah->ah_nh);
1091 ah->ah_hl = (rplen + ahx->authsize - AH_FLENGTH) / sizeof(u_int32_t);
1092 ah->ah_rv = 0;
1093 ah->ah_spi = tdb->tdb_spi;
1094
1095 /* Zeroize authenticator. */
1096 m_copyback(m, skip + rplen, ahx->authsize, ipseczeroes);
1097
1098 if (!(tdb->tdb_flags & TDBF_NOREPLAY))
1099 ah->ah_rpl = htonl(tdb->tdb_rpl++);
1100
1101 /* Get crypto descriptors. */
1102 crp = crypto_getreq(1);
1103 if (crp == NULL) {
1104 m_freem(m);
1105 DPRINTF(("ah_output(): failed to acquire crypto "
1106 "descriptors\n"));
1107 ahstat.ahs_crypto++;
1108 return ENOBUFS;
1109 }
1110
1111 crda = crp->crp_desc;
1112
1113 crda->crd_skip = 0;
1114 crda->crd_inject = skip + rplen;
1115 crda->crd_len = m->m_pkthdr.len;
1116
1117 /* Authentication operation. */
1118 crda->crd_alg = ahx->type;
1119 crda->crd_key = tdb->tdb_amxkey;
1120 crda->crd_klen = tdb->tdb_amxkeylen * 8;
1121
1122 /* Allocate IPsec-specific opaque crypto info. */
1123 if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0)
1124 MALLOC(tc, struct tdb_crypto *,
1125 sizeof(struct tdb_crypto) + skip, M_XDATA, M_NOWAIT);
1126 else
1127 MALLOC(tc, struct tdb_crypto *,
1128 sizeof(struct tdb_crypto), M_XDATA, M_NOWAIT);
1129 if (tc == NULL) {
1130 m_freem(m);
1131 crypto_freereq(crp);
1132 DPRINTF(("ah_output(): failed to allocate tdb_crypto\n"));
1133 ahstat.ahs_crypto++;
1134 return ENOBUFS;
1135 }
1136
1137 bzero(tc, sizeof(struct tdb_crypto));
1138
1139 /* Save the skipped portion of the packet. */
1140 if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0) {
1141 m_copydata(m, 0, skip, (caddr_t) (tc + 1));
1142
1143 /*
1144 * Fix IP header length on the header used for
1145 * authentication. We don't need to fix the original
1146 * header length as it will be fixed by our caller.
1147 */
1148 switch (tdb->tdb_dst.sa.sa_family) {
1149 #ifdef INET
1150 case AF_INET:
1151 bcopy(((caddr_t)(tc + 1)) +
1152 offsetof(struct ip, ip_len),
1153 (caddr_t) &iplen, sizeof(u_int16_t));
1154 iplen = htons(ntohs(iplen) + rplen + ahx->authsize);
1155 m_copyback(m, offsetof(struct ip, ip_len),
1156 sizeof(u_int16_t), &iplen);
1157 break;
1158 #endif /* INET */
1159
1160 #ifdef INET6
1161 case AF_INET6:
1162 bcopy(((caddr_t)(tc + 1)) +
1163 offsetof(struct ip6_hdr, ip6_plen),
1164 (caddr_t) &iplen, sizeof(u_int16_t));
1165 iplen = htons(ntohs(iplen) + rplen + ahx->authsize);
1166 m_copyback(m, offsetof(struct ip6_hdr, ip6_plen),
1167 sizeof(u_int16_t), &iplen);
1168 break;
1169 #endif /* INET6 */
1170 }
1171
1172 /* Fix the Next Header field in saved header. */
1173 ((u_int8_t *) (tc + 1))[protoff] = IPPROTO_AH;
1174
1175 /* Update the Next Protocol field in the IP header. */
1176 prot = IPPROTO_AH;
1177 m_copyback(m, protoff, sizeof(u_int8_t), &prot);
1178
1179 /* "Massage" the packet headers for crypto processing. */
1180 if ((len = ah_massage_headers(&m, tdb->tdb_dst.sa.sa_family,
1181 skip, ahx->type, 1)) != 0) {
1182 /* mbuf will be free'd by callee. */
1183 FREE(tc, M_XDATA);
1184 crypto_freereq(crp);
1185 return len;
1186 }
1187 } else {
1188 /* Update the Next Protocol field in the IP header. */
1189 prot = IPPROTO_AH;
1190 m_copyback(m, protoff, sizeof(u_int8_t), &prot);
1191 }
1192
1193 /* Crypto operation descriptor. */
1194 crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */
1195 crp->crp_flags = CRYPTO_F_IMBUF;
1196 crp->crp_buf = (caddr_t) m;
1197 crp->crp_callback = (int (*) (struct cryptop *)) ah_output_cb;
1198 crp->crp_sid = tdb->tdb_cryptoid;
1199 crp->crp_opaque = (caddr_t) tc;
1200
1201 /* These are passed as-is to the callback. */
1202 tc->tc_skip = skip;
1203 tc->tc_protoff = protoff;
1204 tc->tc_spi = tdb->tdb_spi;
1205 tc->tc_proto = tdb->tdb_sproto;
1206 bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
1207
1208 if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0)
1209 return crypto_dispatch(crp);
1210 else
1211 return ah_output_cb(crp);
1212 }
1213
1214 /*
1215 * AH output callback, called directly from the crypto handler.
1216 */
1217 int
ah_output_cb(void * op)1218 ah_output_cb(void *op)
1219 {
1220 int skip, protoff, error = 0;
1221 struct tdb_crypto *tc;
1222 struct cryptop *crp;
1223 struct tdb *tdb;
1224 struct mbuf *m;
1225 caddr_t ptr;
1226 int err, s;
1227
1228 crp = (struct cryptop *) op;
1229 tc = (struct tdb_crypto *) crp->crp_opaque;
1230 skip = tc->tc_skip;
1231 protoff = tc->tc_protoff;
1232 ptr = (caddr_t) (tc + 1);
1233
1234 m = (struct mbuf *) crp->crp_buf;
1235 if (m == NULL) {
1236 /* Shouldn't happen... */
1237 FREE(tc, M_XDATA);
1238 crypto_freereq(crp);
1239 ahstat.ahs_crypto++;
1240 DPRINTF(("ah_output_cb(): bogus returned buffer from "
1241 "crypto\n"));
1242 return (EINVAL);
1243 }
1244
1245 s = spltdb();
1246
1247 tdb = gettdb(tc->tc_spi, &tc->tc_dst, tc->tc_proto);
1248 if (tdb == NULL) {
1249 FREE(tc, M_XDATA);
1250 ahstat.ahs_notdb++;
1251 DPRINTF(("ah_output_cb(): TDB is expired while in crypto\n"));
1252 error = EPERM;
1253 goto baddone;
1254 }
1255
1256 /* Check for crypto errors. */
1257 if (crp->crp_etype) {
1258 if (crp->crp_etype == EAGAIN) {
1259 /* Reset the session ID */
1260 if (tdb->tdb_cryptoid != 0)
1261 tdb->tdb_cryptoid = crp->crp_sid;
1262 splx(s);
1263 return crypto_dispatch(crp);
1264 }
1265 FREE(tc, M_XDATA);
1266 ahstat.ahs_noxform++;
1267 DPRINTF(("ah_output_cb(): crypto error %d\n", crp->crp_etype));
1268 error = crp->crp_etype;
1269 goto baddone;
1270 }
1271
1272 /*
1273 * Copy original headers (with the new protocol number) back
1274 * in place.
1275 */
1276 if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0)
1277 m_copyback(m, 0, skip, ptr);
1278
1279 FREE(tc, M_XDATA);
1280
1281 /* No longer needed. */
1282 crypto_freereq(crp);
1283
1284 err = ipsp_process_done(m, tdb);
1285 splx(s);
1286 return err;
1287
1288 baddone:
1289 splx(s);
1290
1291 if (m != NULL)
1292 m_freem(m);
1293
1294 crypto_freereq(crp);
1295
1296 return error;
1297 }
1298