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