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