Remove macro definitions for BPF_MTAP
[dragonfly.git] / sys / netinet6 / esp_input.c
1 /*      $FreeBSD: src/sys/netinet6/esp_input.c,v 1.1.2.8 2003/01/23 21:06:47 sam Exp $  */
2 /*      $DragonFly: src/sys/netinet6/esp_input.c,v 1.5 2003/09/15 23:38:14 hsu Exp $    */
3 /*      $KAME: esp_input.c,v 1.62 2002/01/07 11:39:57 kjc Exp $ */
4
5 /*
6  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of the project nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33
34 /*
35  * RFC1827/2406 Encapsulated Security Payload.
36  */
37
38 #include "opt_inet.h"
39 #include "opt_inet6.h"
40
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/mbuf.h>
44 #include <sys/domain.h>
45 #include <sys/protosw.h>
46 #include <sys/socket.h>
47 #include <sys/errno.h>
48 #include <sys/time.h>
49 #include <sys/syslog.h>
50
51 #include <net/if.h>
52 #include <net/route.h>
53 #include <net/netisr.h>
54 #include <machine/cpu.h>
55
56 #include <netinet/in.h>
57 #include <netinet/in_systm.h>
58 #include <netinet/ip.h>
59 #include <netinet/ip_var.h>
60 #include <netinet/in_var.h>
61 #include <netinet/ip_ecn.h>
62 #ifdef INET6
63 #include <netinet6/ip6_ecn.h>
64 #endif
65
66 #ifdef INET6
67 #include <netinet/ip6.h>
68 #include <netinet6/in6_pcb.h>
69 #include <netinet6/ip6_var.h>
70 #include <netinet/icmp6.h>
71 #include <netinet6/ip6protosw.h>
72 #endif
73
74 #include <netinet6/ipsec.h>
75 #ifdef INET6
76 #include <netinet6/ipsec6.h>
77 #endif
78 #include <netinet6/ah.h>
79 #ifdef INET6
80 #include <netinet6/ah6.h>
81 #endif
82 #include <netinet6/esp.h>
83 #ifdef INET6
84 #include <netinet6/esp6.h>
85 #endif
86 #include <netproto/key/key.h>
87 #include <netproto/key/keydb.h>
88 #include <netproto/key/key_debug.h>
89
90 #include <machine/stdarg.h>
91
92 #include <net/net_osdep.h>
93
94 #define IPLEN_FLIPPED
95
96 #define ESPMAXLEN \
97         (sizeof(struct esp) < sizeof(struct newesp) \
98                 ? sizeof(struct newesp) : sizeof(struct esp))
99
100 #ifdef INET
101 #include <netinet/ipprotosw.h>
102 extern struct ipprotosw inetsw[];
103
104 void
105 esp4_input(struct mbuf *m, int off, int proto)
106 {
107         struct ip *ip;
108         struct esp *esp;
109         struct esptail esptail;
110         u_int32_t spi;
111         struct secasvar *sav = NULL;
112         size_t taillen;
113         u_int16_t nxt;
114         const struct esp_algorithm *algo;
115         int ivlen;
116         size_t hlen;
117         size_t esplen;
118
119         /* sanity check for alignment. */
120         if (off % 4 != 0 || m->m_pkthdr.len % 4 != 0) {
121                 ipseclog((LOG_ERR, "IPv4 ESP input: packet alignment problem "
122                         "(off=%d, pktlen=%d)\n", off, m->m_pkthdr.len));
123                 ipsecstat.in_inval++;
124                 goto bad;
125         }
126
127         if (m->m_len < off + ESPMAXLEN) {
128                 m = m_pullup(m, off + ESPMAXLEN);
129                 if (!m) {
130                         ipseclog((LOG_DEBUG,
131                             "IPv4 ESP input: can't pullup in esp4_input\n"));
132                         ipsecstat.in_inval++;
133                         goto bad;
134                 }
135         }
136
137         ip = mtod(m, struct ip *);
138         esp = (struct esp *)(((u_int8_t *)ip) + off);
139 #ifdef _IP_VHL
140         hlen = IP_VHL_HL(ip->ip_vhl) << 2;
141 #else
142         hlen = ip->ip_hl << 2;
143 #endif
144
145         /* find the sassoc. */
146         spi = esp->esp_spi;
147
148         if ((sav = key_allocsa(AF_INET,
149                               (caddr_t)&ip->ip_src, (caddr_t)&ip->ip_dst,
150                               IPPROTO_ESP, spi)) == 0) {
151                 ipseclog((LOG_WARNING,
152                     "IPv4 ESP input: no key association found for spi %u\n",
153                     (u_int32_t)ntohl(spi)));
154                 ipsecstat.in_nosa++;
155                 goto bad;
156         }
157         KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
158                 printf("DP esp4_input called to allocate SA:%p\n", sav));
159         if (sav->state != SADB_SASTATE_MATURE
160          && sav->state != SADB_SASTATE_DYING) {
161                 ipseclog((LOG_DEBUG,
162                     "IPv4 ESP input: non-mature/dying SA found for spi %u\n",
163                     (u_int32_t)ntohl(spi)));
164                 ipsecstat.in_badspi++;
165                 goto bad;
166         }
167         algo = esp_algorithm_lookup(sav->alg_enc);
168         if (!algo) {
169                 ipseclog((LOG_DEBUG, "IPv4 ESP input: "
170                     "unsupported encryption algorithm for spi %u\n",
171                     (u_int32_t)ntohl(spi)));
172                 ipsecstat.in_badspi++;
173                 goto bad;
174         }
175
176         /* check if we have proper ivlen information */
177         ivlen = sav->ivlen;
178         if (ivlen < 0) {
179                 ipseclog((LOG_ERR, "inproper ivlen in IPv4 ESP input: %s %s\n",
180                     ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
181                 ipsecstat.in_inval++;
182                 goto bad;
183         }
184
185         if (!((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay
186          && (sav->alg_auth && sav->key_auth)))
187                 goto noreplaycheck;
188
189         if (sav->alg_auth == SADB_X_AALG_NULL ||
190             sav->alg_auth == SADB_AALG_NONE)
191                 goto noreplaycheck;
192
193         /*
194          * check for sequence number.
195          */
196         if (ipsec_chkreplay(ntohl(((struct newesp *)esp)->esp_seq), sav))
197                 ; /* okey */
198         else {
199                 ipsecstat.in_espreplay++;
200                 ipseclog((LOG_WARNING,
201                     "replay packet in IPv4 ESP input: %s %s\n",
202                     ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
203                 goto bad;
204         }
205
206         /* check ICV */
207     {
208         u_char sum0[AH_MAXSUMSIZE];
209         u_char sum[AH_MAXSUMSIZE];
210         const struct ah_algorithm *sumalgo;
211         size_t siz;
212
213         sumalgo = ah_algorithm_lookup(sav->alg_auth);
214         if (!sumalgo)
215                 goto noreplaycheck;
216         siz = (((*sumalgo->sumsiz)(sav) + 3) & ~(4 - 1));
217         if (m->m_pkthdr.len < off + ESPMAXLEN + siz) {
218                 ipsecstat.in_inval++;
219                 goto bad;
220         }
221         if (AH_MAXSUMSIZE < siz) {
222                 ipseclog((LOG_DEBUG,
223                     "internal error: AH_MAXSUMSIZE must be larger than %lu\n",
224                     (u_long)siz));
225                 ipsecstat.in_inval++;
226                 goto bad;
227         }
228
229         m_copydata(m, m->m_pkthdr.len - siz, siz, &sum0[0]);
230
231         if (esp_auth(m, off, m->m_pkthdr.len - off - siz, sav, sum)) {
232                 ipseclog((LOG_WARNING, "auth fail in IPv4 ESP input: %s %s\n",
233                     ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
234                 ipsecstat.in_espauthfail++;
235                 goto bad;
236         }
237
238         if (bcmp(sum0, sum, siz) != 0) {
239                 ipseclog((LOG_WARNING, "auth fail in IPv4 ESP input: %s %s\n",
240                     ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
241                 ipsecstat.in_espauthfail++;
242                 goto bad;
243         }
244
245         /* strip off the authentication data */
246         m_adj(m, -siz);
247         ip = mtod(m, struct ip *);
248 #ifdef IPLEN_FLIPPED
249         ip->ip_len = ip->ip_len - siz;
250 #else
251         ip->ip_len = htons(ntohs(ip->ip_len) - siz);
252 #endif
253         m->m_flags |= M_AUTHIPDGM;
254         ipsecstat.in_espauthsucc++;
255     }
256
257         /*
258          * update sequence number.
259          */
260         if ((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay) {
261                 if (ipsec_updatereplay(ntohl(((struct newesp *)esp)->esp_seq), sav)) {
262                         ipsecstat.in_espreplay++;
263                         goto bad;
264                 }
265         }
266
267 noreplaycheck:
268
269         /* process main esp header. */
270         if (sav->flags & SADB_X_EXT_OLD) {
271                 /* RFC 1827 */
272                 esplen = sizeof(struct esp);
273         } else {
274                 /* RFC 2406 */
275                 if (sav->flags & SADB_X_EXT_DERIV)
276                         esplen = sizeof(struct esp);
277                 else
278                         esplen = sizeof(struct newesp);
279         }
280
281         if (m->m_pkthdr.len < off + esplen + ivlen + sizeof(esptail)) {
282                 ipseclog((LOG_WARNING,
283                     "IPv4 ESP input: packet too short\n"));
284                 ipsecstat.in_inval++;
285                 goto bad;
286         }
287
288         if (m->m_len < off + esplen + ivlen) {
289                 m = m_pullup(m, off + esplen + ivlen);
290                 if (!m) {
291                         ipseclog((LOG_DEBUG,
292                             "IPv4 ESP input: can't pullup in esp4_input\n"));
293                         ipsecstat.in_inval++;
294                         goto bad;
295                 }
296         }
297
298         /*
299          * pre-compute and cache intermediate key
300          */
301         if (esp_schedule(algo, sav) != 0) {
302                 ipsecstat.in_inval++;
303                 goto bad;
304         }
305
306         /*
307          * decrypt the packet.
308          */
309         if (!algo->decrypt)
310                 panic("internal error: no decrypt function");
311         if ((*algo->decrypt)(m, off, sav, algo, ivlen)) {
312                 /* m is already freed */
313                 m = NULL;
314                 ipseclog((LOG_ERR, "decrypt fail in IPv4 ESP input: %s\n",
315                     ipsec_logsastr(sav)));
316                 ipsecstat.in_inval++;
317                 goto bad;
318         }
319         ipsecstat.in_esphist[sav->alg_enc]++;
320
321         m->m_flags |= M_DECRYPTED;
322
323         /*
324          * find the trailer of the ESP.
325          */
326         m_copydata(m, m->m_pkthdr.len - sizeof(esptail), sizeof(esptail),
327              (caddr_t)&esptail);
328         nxt = esptail.esp_nxt;
329         taillen = esptail.esp_padlen + sizeof(esptail);
330
331         if (m->m_pkthdr.len < taillen
332          || m->m_pkthdr.len - taillen < hlen) { /* ? */
333                 ipseclog((LOG_WARNING,
334                     "bad pad length in IPv4 ESP input: %s %s\n",
335                     ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
336                 ipsecstat.in_inval++;
337                 goto bad;
338         }
339
340         /* strip off the trailing pad area. */
341         m_adj(m, -taillen);
342
343 #ifdef IPLEN_FLIPPED
344         ip->ip_len = ip->ip_len - taillen;
345 #else
346         ip->ip_len = htons(ntohs(ip->ip_len) - taillen);
347 #endif
348
349         /* was it transmitted over the IPsec tunnel SA? */
350         if (ipsec4_tunnel_validate(m, off + esplen + ivlen, nxt, sav)) {
351                 /*
352                  * strip off all the headers that precedes ESP header.
353                  *      IP4 xx ESP IP4' payload -> IP4' payload
354                  *
355                  * XXX more sanity checks
356                  * XXX relationship with gif?
357                  */
358                 u_int8_t tos;
359
360                 tos = ip->ip_tos;
361                 m_adj(m, off + esplen + ivlen);
362                 if (m->m_len < sizeof(*ip)) {
363                         m = m_pullup(m, sizeof(*ip));
364                         if (!m) {
365                                 ipsecstat.in_inval++;
366                                 goto bad;
367                         }
368                 }
369                 ip = mtod(m, struct ip *);
370                 /* ECN consideration. */
371                 ip_ecn_egress(ip4_ipsec_ecn, &tos, &ip->ip_tos);
372                 if (!key_checktunnelsanity(sav, AF_INET,
373                             (caddr_t)&ip->ip_src, (caddr_t)&ip->ip_dst)) {
374                         ipseclog((LOG_ERR, "ipsec tunnel address mismatch "
375                             "in IPv4 ESP input: %s %s\n",
376                             ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav)));
377                         ipsecstat.in_inval++;
378                         goto bad;
379                 }
380
381                 key_sa_recordxfer(sav, m);
382                 if (ipsec_addhist(m, IPPROTO_ESP, spi) != 0 ||
383                     ipsec_addhist(m, IPPROTO_IPV4, 0) != 0) {
384                         ipsecstat.in_nomem++;
385                         goto bad;
386                 }
387
388                 if (netisr_queue(NETISR_IP, m)) {
389                         ipsecstat.in_inval++;
390                         m = NULL;
391                         goto bad;
392                 }
393
394                 nxt = IPPROTO_DONE;
395         } else {
396                 /*
397                  * strip off ESP header and IV.
398                  * even in m_pulldown case, we need to strip off ESP so that
399                  * we can always compute checksum for AH correctly.
400                  */
401                 size_t stripsiz;
402
403                 stripsiz = esplen + ivlen;
404
405                 ip = mtod(m, struct ip *);
406                 ovbcopy((caddr_t)ip, (caddr_t)(((u_char *)ip) + stripsiz), off);
407                 m->m_data += stripsiz;
408                 m->m_len -= stripsiz;
409                 m->m_pkthdr.len -= stripsiz;
410
411                 ip = mtod(m, struct ip *);
412 #ifdef IPLEN_FLIPPED
413                 ip->ip_len = ip->ip_len - stripsiz;
414 #else
415                 ip->ip_len = htons(ntohs(ip->ip_len) - stripsiz);
416 #endif
417                 ip->ip_p = nxt;
418
419                 key_sa_recordxfer(sav, m);
420                 if (ipsec_addhist(m, IPPROTO_ESP, spi) != 0) {
421                         ipsecstat.in_nomem++;
422                         goto bad;
423                 }
424
425                 if (nxt != IPPROTO_DONE) {
426                         if ((inetsw[ip_protox[nxt]].pr_flags & PR_LASTHDR) != 0 &&
427                             ipsec4_in_reject(m, NULL)) {
428                                 ipsecstat.in_polvio++;
429                                 goto bad;
430                         }
431                         (*inetsw[ip_protox[nxt]].pr_input)(m, off, nxt);
432                 } else
433                         m_freem(m);
434                 m = NULL;
435         }
436
437         if (sav) {
438                 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
439                         printf("DP esp4_input call free SA:%p\n", sav));
440                 key_freesav(sav);
441         }
442         ipsecstat.in_success++;
443         return;
444
445 bad:
446         if (sav) {
447                 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
448                         printf("DP esp4_input call free SA:%p\n", sav));
449                 key_freesav(sav);
450         }
451         if (m)
452                 m_freem(m);
453         return;
454 }
455 #endif /* INET */
456
457 #ifdef INET6
458 int
459 esp6_input(mp, offp, proto)
460         struct mbuf **mp;
461         int *offp, proto;
462 {
463         struct mbuf *m = *mp;
464         int off = *offp;
465         struct ip6_hdr *ip6;
466         struct esp *esp;
467         struct esptail esptail;
468         u_int32_t spi;
469         struct secasvar *sav = NULL;
470         size_t taillen;
471         u_int16_t nxt;
472         const struct esp_algorithm *algo;
473         int ivlen;
474         size_t esplen;
475
476         /* sanity check for alignment. */
477         if (off % 4 != 0 || m->m_pkthdr.len % 4 != 0) {
478                 ipseclog((LOG_ERR, "IPv6 ESP input: packet alignment problem "
479                         "(off=%d, pktlen=%d)\n", off, m->m_pkthdr.len));
480                 ipsec6stat.in_inval++;
481                 goto bad;
482         }
483
484 #ifndef PULLDOWN_TEST
485         IP6_EXTHDR_CHECK(m, off, ESPMAXLEN, IPPROTO_DONE);
486         esp = (struct esp *)(mtod(m, caddr_t) + off);
487 #else
488         IP6_EXTHDR_GET(esp, struct esp *, m, off, ESPMAXLEN);
489         if (esp == NULL) {
490                 ipsec6stat.in_inval++;
491                 return IPPROTO_DONE;
492         }
493 #endif
494         ip6 = mtod(m, struct ip6_hdr *);
495
496         if (ntohs(ip6->ip6_plen) == 0) {
497                 ipseclog((LOG_ERR, "IPv6 ESP input: "
498                     "ESP with IPv6 jumbogram is not supported.\n"));
499                 ipsec6stat.in_inval++;
500                 goto bad;
501         }
502
503         /* find the sassoc. */
504         spi = esp->esp_spi;
505
506         if ((sav = key_allocsa(AF_INET6,
507                               (caddr_t)&ip6->ip6_src, (caddr_t)&ip6->ip6_dst,
508                               IPPROTO_ESP, spi)) == 0) {
509                 ipseclog((LOG_WARNING,
510                     "IPv6 ESP input: no key association found for spi %u\n",
511                     (u_int32_t)ntohl(spi)));
512                 ipsec6stat.in_nosa++;
513                 goto bad;
514         }
515         KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
516                 printf("DP esp6_input called to allocate SA:%p\n", sav));
517         if (sav->state != SADB_SASTATE_MATURE
518          && sav->state != SADB_SASTATE_DYING) {
519                 ipseclog((LOG_DEBUG,
520                     "IPv6 ESP input: non-mature/dying SA found for spi %u\n",
521                     (u_int32_t)ntohl(spi)));
522                 ipsec6stat.in_badspi++;
523                 goto bad;
524         }
525         algo = esp_algorithm_lookup(sav->alg_enc);
526         if (!algo) {
527                 ipseclog((LOG_DEBUG, "IPv6 ESP input: "
528                     "unsupported encryption algorithm for spi %u\n",
529                     (u_int32_t)ntohl(spi)));
530                 ipsec6stat.in_badspi++;
531                 goto bad;
532         }
533
534         /* check if we have proper ivlen information */
535         ivlen = sav->ivlen;
536         if (ivlen < 0) {
537                 ipseclog((LOG_ERR, "inproper ivlen in IPv6 ESP input: %s %s\n",
538                     ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav)));
539                 ipsec6stat.in_badspi++;
540                 goto bad;
541         }
542
543         if (!((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay
544          && (sav->alg_auth && sav->key_auth)))
545                 goto noreplaycheck;
546
547         if (sav->alg_auth == SADB_X_AALG_NULL ||
548             sav->alg_auth == SADB_AALG_NONE)
549                 goto noreplaycheck;
550
551         /*
552          * check for sequence number.
553          */
554         if (ipsec_chkreplay(ntohl(((struct newesp *)esp)->esp_seq), sav))
555                 ; /* okey */
556         else {
557                 ipsec6stat.in_espreplay++;
558                 ipseclog((LOG_WARNING,
559                     "replay packet in IPv6 ESP input: %s %s\n",
560                     ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav)));
561                 goto bad;
562         }
563
564         /* check ICV */
565     {
566         u_char sum0[AH_MAXSUMSIZE];
567         u_char sum[AH_MAXSUMSIZE];
568         const struct ah_algorithm *sumalgo;
569         size_t siz;
570
571         sumalgo = ah_algorithm_lookup(sav->alg_auth);
572         if (!sumalgo)
573                 goto noreplaycheck;
574         siz = (((*sumalgo->sumsiz)(sav) + 3) & ~(4 - 1));
575         if (m->m_pkthdr.len < off + ESPMAXLEN + siz) {
576                 ipsecstat.in_inval++;
577                 goto bad;
578         }
579         if (AH_MAXSUMSIZE < siz) {
580                 ipseclog((LOG_DEBUG,
581                     "internal error: AH_MAXSUMSIZE must be larger than %lu\n",
582                     (u_long)siz));
583                 ipsec6stat.in_inval++;
584                 goto bad;
585         }
586
587         m_copydata(m, m->m_pkthdr.len - siz, siz, &sum0[0]);
588
589         if (esp_auth(m, off, m->m_pkthdr.len - off - siz, sav, sum)) {
590                 ipseclog((LOG_WARNING, "auth fail in IPv6 ESP input: %s %s\n",
591                     ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav)));
592                 ipsec6stat.in_espauthfail++;
593                 goto bad;
594         }
595
596         if (bcmp(sum0, sum, siz) != 0) {
597                 ipseclog((LOG_WARNING, "auth fail in IPv6 ESP input: %s %s\n",
598                     ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav)));
599                 ipsec6stat.in_espauthfail++;
600                 goto bad;
601         }
602
603         /* strip off the authentication data */
604         m_adj(m, -siz);
605         ip6 = mtod(m, struct ip6_hdr *);
606         ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - siz);
607
608         m->m_flags |= M_AUTHIPDGM;
609         ipsec6stat.in_espauthsucc++;
610     }
611
612         /*
613          * update sequence number.
614          */
615         if ((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay) {
616                 if (ipsec_updatereplay(ntohl(((struct newesp *)esp)->esp_seq), sav)) {
617                         ipsec6stat.in_espreplay++;
618                         goto bad;
619                 }
620         }
621
622 noreplaycheck:
623
624         /* process main esp header. */
625         if (sav->flags & SADB_X_EXT_OLD) {
626                 /* RFC 1827 */
627                 esplen = sizeof(struct esp);
628         } else {
629                 /* RFC 2406 */
630                 if (sav->flags & SADB_X_EXT_DERIV)
631                         esplen = sizeof(struct esp);
632                 else
633                         esplen = sizeof(struct newesp);
634         }
635
636         if (m->m_pkthdr.len < off + esplen + ivlen + sizeof(esptail)) {
637                 ipseclog((LOG_WARNING,
638                     "IPv6 ESP input: packet too short\n"));
639                 ipsec6stat.in_inval++;
640                 goto bad;
641         }
642
643 #ifndef PULLDOWN_TEST
644         IP6_EXTHDR_CHECK(m, off, esplen + ivlen, IPPROTO_DONE); /* XXX */
645 #else
646         IP6_EXTHDR_GET(esp, struct esp *, m, off, esplen + ivlen);
647         if (esp == NULL) {
648                 ipsec6stat.in_inval++;
649                 m = NULL;
650                 goto bad;
651         }
652 #endif
653         ip6 = mtod(m, struct ip6_hdr *);        /* set it again just in case */
654
655         /*
656          * pre-compute and cache intermediate key
657          */
658         if (esp_schedule(algo, sav) != 0) {
659                 ipsec6stat.in_inval++;
660                 goto bad;
661         }
662
663         /*
664          * decrypt the packet.
665          */
666         if (!algo->decrypt)
667                 panic("internal error: no decrypt function");
668         if ((*algo->decrypt)(m, off, sav, algo, ivlen)) {
669                 /* m is already freed */
670                 m = NULL;
671                 ipseclog((LOG_ERR, "decrypt fail in IPv6 ESP input: %s\n",
672                     ipsec_logsastr(sav)));
673                 ipsec6stat.in_inval++;
674                 goto bad;
675         }
676         ipsec6stat.in_esphist[sav->alg_enc]++;
677
678         m->m_flags |= M_DECRYPTED;
679
680         /*
681          * find the trailer of the ESP.
682          */
683         m_copydata(m, m->m_pkthdr.len - sizeof(esptail), sizeof(esptail),
684              (caddr_t)&esptail);
685         nxt = esptail.esp_nxt;
686         taillen = esptail.esp_padlen + sizeof(esptail);
687
688         if (m->m_pkthdr.len < taillen
689          || m->m_pkthdr.len - taillen < sizeof(struct ip6_hdr)) {       /* ? */
690                 ipseclog((LOG_WARNING,
691                     "bad pad length in IPv6 ESP input: %s %s\n",
692                     ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav)));
693                 ipsec6stat.in_inval++;
694                 goto bad;
695         }
696
697         /* strip off the trailing pad area. */
698         m_adj(m, -taillen);
699
700         ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - taillen);
701
702         /* was it transmitted over the IPsec tunnel SA? */
703         if (ipsec6_tunnel_validate(m, off + esplen + ivlen, nxt, sav)) {
704                 /*
705                  * strip off all the headers that precedes ESP header.
706                  *      IP6 xx ESP IP6' payload -> IP6' payload
707                  *
708                  * XXX more sanity checks
709                  * XXX relationship with gif?
710                  */
711                 u_int32_t flowinfo;     /* net endian */
712                 flowinfo = ip6->ip6_flow;
713                 m_adj(m, off + esplen + ivlen);
714                 if (m->m_len < sizeof(*ip6)) {
715 #ifndef PULLDOWN_TEST
716                         /*
717                          * m_pullup is prohibited in KAME IPv6 input processing
718                          * but there's no other way!
719                          */
720 #else
721                         /* okay to pullup in m_pulldown style */
722 #endif
723                         m = m_pullup(m, sizeof(*ip6));
724                         if (!m) {
725                                 ipsec6stat.in_inval++;
726                                 goto bad;
727                         }
728                 }
729                 ip6 = mtod(m, struct ip6_hdr *);
730                 /* ECN consideration. */
731                 ip6_ecn_egress(ip6_ipsec_ecn, &flowinfo, &ip6->ip6_flow);
732                 if (!key_checktunnelsanity(sav, AF_INET6,
733                             (caddr_t)&ip6->ip6_src, (caddr_t)&ip6->ip6_dst)) {
734                         ipseclog((LOG_ERR, "ipsec tunnel address mismatch "
735                             "in IPv6 ESP input: %s %s\n",
736                             ipsec6_logpacketstr(ip6, spi),
737                             ipsec_logsastr(sav)));
738                         ipsec6stat.in_inval++;
739                         goto bad;
740                 }
741
742                 key_sa_recordxfer(sav, m);
743                 if (ipsec_addhist(m, IPPROTO_ESP, spi) != 0 || 
744                     ipsec_addhist(m, IPPROTO_IPV6, 0) != 0) {
745                         ipsec6stat.in_nomem++;
746                         goto bad;
747                 }
748
749                 if (netisr_queue(NETISR_IPV6, m)) {
750                         ipsec6stat.in_inval++;
751                         m = NULL;
752                         goto bad;
753                 }
754
755                 nxt = IPPROTO_DONE;
756         } else {
757                 /*
758                  * strip off ESP header and IV.
759                  * even in m_pulldown case, we need to strip off ESP so that
760                  * we can always compute checksum for AH correctly.
761                  */
762                 size_t stripsiz;
763                 char *prvnxtp;
764
765                 /*
766                  * Set the next header field of the previous header correctly.
767                  */
768                 prvnxtp = ip6_get_prevhdr(m, off); /* XXX */
769                 *prvnxtp = nxt;
770
771                 stripsiz = esplen + ivlen;
772
773                 ip6 = mtod(m, struct ip6_hdr *);
774                 if (m->m_len >= stripsiz + off) {
775                         ovbcopy((caddr_t)ip6, ((caddr_t)ip6) + stripsiz, off);
776                         m->m_data += stripsiz;
777                         m->m_len -= stripsiz;
778                         m->m_pkthdr.len -= stripsiz;
779                 } else {
780                         /*
781                          * this comes with no copy if the boundary is on
782                          * cluster
783                          */
784                         struct mbuf *n;
785
786                         n = m_split(m, off, M_DONTWAIT);
787                         if (n == NULL) {
788                                 /* m is retained by m_split */
789                                 goto bad;
790                         }
791                         m_adj(n, stripsiz);
792                         m_cat(m, n);
793                         /* m_cat does not update m_pkthdr.len */
794                         m->m_pkthdr.len += n->m_pkthdr.len;
795                 }
796
797 #ifndef PULLDOWN_TEST
798                 /*
799                  * KAME requires that the packet to be contiguous on the
800                  * mbuf.  We need to make that sure.
801                  * this kind of code should be avoided.
802                  * XXX other conditions to avoid running this part?
803                  */
804                 if (m->m_len != m->m_pkthdr.len) {
805                         struct mbuf *n = NULL;
806                         int maxlen;
807
808                         MGETHDR(n, M_DONTWAIT, MT_HEADER);
809                         maxlen = MHLEN;
810                         if (n)
811                                 M_MOVE_PKTHDR(n, m);
812                         if (n && n->m_pkthdr.len > maxlen) {
813                                 MCLGET(n, M_DONTWAIT);
814                                 maxlen = MCLBYTES;
815                                 if ((n->m_flags & M_EXT) == 0) {
816                                         m_free(n);
817                                         n = NULL;
818                                 }
819                         }
820                         if (!n) {
821                                 printf("esp6_input: mbuf allocation failed\n");
822                                 goto bad;
823                         }
824
825                         if (n->m_pkthdr.len <= maxlen) {
826                                 m_copydata(m, 0, n->m_pkthdr.len, mtod(n, caddr_t));
827                                 n->m_len = n->m_pkthdr.len;
828                                 n->m_next = NULL;
829                                 m_freem(m);
830                         } else {
831                                 m_copydata(m, 0, maxlen, mtod(n, caddr_t));
832                                 n->m_len = maxlen;
833                                 n->m_next = m;
834                                 m_adj(m, maxlen);
835                         }
836                         m = n;
837                 }
838 #endif
839
840                 ip6 = mtod(m, struct ip6_hdr *);
841                 ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - stripsiz);
842
843                 key_sa_recordxfer(sav, m);
844                 if (ipsec_addhist(m, IPPROTO_ESP, spi) != 0) {
845                         ipsec6stat.in_nomem++;
846                         goto bad;
847                 }
848         }
849
850         *offp = off;
851         *mp = m;
852
853         if (sav) {
854                 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
855                         printf("DP esp6_input call free SA:%p\n", sav));
856                 key_freesav(sav);
857         }
858         ipsec6stat.in_success++;
859         return nxt;
860
861 bad:
862         if (sav) {
863                 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
864                         printf("DP esp6_input call free SA:%p\n", sav));
865                 key_freesav(sav);
866         }
867         if (m)
868                 m_freem(m);
869         return IPPROTO_DONE;
870 }
871
872 void
873 esp6_ctlinput(cmd, sa, d)
874         int cmd;
875         struct sockaddr *sa;
876         void *d;
877 {
878         const struct newesp *espp;
879         struct newesp esp;
880         struct ip6ctlparam *ip6cp = NULL, ip6cp1;
881         struct secasvar *sav;
882         struct ip6_hdr *ip6;
883         struct mbuf *m;
884         int off;
885         struct sockaddr_in6 *sa6_src, *sa6_dst;
886
887         if (sa->sa_family != AF_INET6 ||
888             sa->sa_len != sizeof(struct sockaddr_in6))
889                 return;
890         if ((unsigned)cmd >= PRC_NCMDS)
891                 return;
892
893         /* if the parameter is from icmp6, decode it. */
894         if (d != NULL) {
895                 ip6cp = (struct ip6ctlparam *)d;
896                 m = ip6cp->ip6c_m;
897                 ip6 = ip6cp->ip6c_ip6;
898                 off = ip6cp->ip6c_off;
899         } else {
900                 m = NULL;
901                 ip6 = NULL;
902                 off = 0; /* fix warning */
903         }
904
905         if (ip6) {
906                 /*
907                  * Notify the error to all possible sockets via pfctlinput2.
908                  * Since the upper layer information (such as protocol type,
909                  * source and destination ports) is embedded in the encrypted
910                  * data and might have been cut, we can't directly call
911                  * an upper layer ctlinput function. However, the pcbnotify
912                  * function will consider source and destination addresses
913                  * as well as the flow info value, and may be able to find
914                  * some PCB that should be notified.
915                  * Although pfctlinput2 will call esp6_ctlinput(), there is
916                  * no possibility of an infinite loop of function calls,
917                  * because we don't pass the inner IPv6 header.
918                  */
919                 bzero(&ip6cp1, sizeof(ip6cp1));
920                 ip6cp1.ip6c_src = ip6cp->ip6c_src;
921                 pfctlinput2(cmd, sa, (void *)&ip6cp1);
922
923                 /*
924                  * Then go to special cases that need ESP header information.
925                  * XXX: We assume that when ip6 is non NULL,
926                  * M and OFF are valid.
927                  */
928
929                 /* check if we can safely examine src and dst ports */
930                 if (m->m_pkthdr.len < off + sizeof(esp))
931                         return;
932
933                 if (m->m_len < off + sizeof(esp)) {
934                         /*
935                          * this should be rare case,
936                          * so we compromise on this copy...
937                          */
938                         m_copydata(m, off, sizeof(esp), (caddr_t)&esp);
939                         espp = &esp;
940                 } else
941                         espp = (struct newesp*)(mtod(m, caddr_t) + off);
942
943                 if (cmd == PRC_MSGSIZE) {
944                         int valid = 0;
945
946                         /*
947                          * Check to see if we have a valid SA corresponding to
948                          * the address in the ICMP message payload.
949                          */
950                         sa6_src = ip6cp->ip6c_src;
951                         sa6_dst = (struct sockaddr_in6 *)sa;
952                         sav = key_allocsa(AF_INET6,
953                                           (caddr_t)&sa6_src->sin6_addr,
954                                           (caddr_t)&sa6_dst->sin6_addr,
955                                           IPPROTO_ESP, espp->esp_spi);
956                         if (sav) {
957                                 if (sav->state == SADB_SASTATE_MATURE ||
958                                     sav->state == SADB_SASTATE_DYING)
959                                         valid++;
960                                 key_freesav(sav);
961                         }
962
963                         /* XXX Further validation? */
964
965                         /*
966                          * Depending on the value of "valid" and routing table
967                          * size (mtudisc_{hi,lo}wat), we will:
968                          * - recalcurate the new MTU and create the
969                          *   corresponding routing entry, or
970                          * - ignore the MTU change notification.
971                          */
972                         icmp6_mtudisc_update((struct ip6ctlparam *)d, valid);
973                 }
974         } else {
975                 /* we normally notify any pcb here */
976         }
977 }
978 #endif /* INET6 */