For kmalloc(), MALLOC() and contigmalloc(), use M_ZERO instead of
[dragonfly.git] / sys / netinet6 / ah_core.c
1 /*      $FreeBSD: src/sys/netinet6/ah_core.c,v 1.2.2.5 2002/04/28 05:40:26 suz Exp $    */
2 /*      $DragonFly: src/sys/netinet6/ah_core.c,v 1.11 2008/01/05 14:02:40 swildner Exp $        */
3 /*      $KAME: ah_core.c,v 1.44 2001/03/12 11:24:39 itojun 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  * RFC1826/2402 authentication header.
36  */
37
38 /* TODO: have shared routines  for hmac-* algorithms */
39
40 #include "opt_inet.h"
41 #include "opt_inet6.h"
42 #include "opt_ipsec.h"
43
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/malloc.h>
47 #include <sys/mbuf.h>
48 #include <sys/domain.h>
49 #include <sys/protosw.h>
50 #include <sys/socket.h>
51 #include <sys/socketvar.h>
52 #include <sys/errno.h>
53 #include <sys/time.h>
54 #include <sys/syslog.h>
55
56 #include <net/if.h>
57 #include <net/route.h>
58
59 #include <netinet/in.h>
60 #include <netinet/in_systm.h>
61 #include <netinet/ip.h>
62 #include <netinet/in_var.h>
63
64 #ifdef INET6
65 #include <netinet/ip6.h>
66 #include <netinet6/ip6_var.h>
67 #include <netinet/icmp6.h>
68 #endif
69
70 #include <netinet6/ipsec.h>
71 #ifdef INET6
72 #include <netinet6/ipsec6.h>
73 #endif
74 #include <netinet6/ah.h>
75 #ifdef INET6
76 #include <netinet6/ah6.h>
77 #endif
78 #ifdef IPSEC_ESP
79 #include <netinet6/esp.h>
80 #ifdef INET6
81 #include <netinet6/esp6.h>
82 #endif
83 #endif
84 #include <net/pfkeyv2.h>
85 #include <netproto/key/keydb.h>
86 #include <sys/md5.h>
87 #include <crypto/sha1.h>
88 #include <crypto/sha2/sha2.h>
89
90 #include <net/net_osdep.h>
91
92 #define HMACSIZE        16
93
94 static int ah_sumsiz_1216 (struct secasvar *);
95 static int ah_sumsiz_zero (struct secasvar *);
96 static int ah_none_mature (struct secasvar *);
97 static int ah_none_init (struct ah_algorithm_state *, struct secasvar *);
98 static void ah_none_loop (struct ah_algorithm_state *, caddr_t, size_t);
99 static void ah_none_result (struct ah_algorithm_state *, caddr_t);
100 static int ah_keyed_md5_mature (struct secasvar *);
101 static int ah_keyed_md5_init (struct ah_algorithm_state *,
102         struct secasvar *);
103 static void ah_keyed_md5_loop (struct ah_algorithm_state *, caddr_t,
104         size_t);
105 static void ah_keyed_md5_result (struct ah_algorithm_state *, caddr_t);
106 static int ah_keyed_sha1_mature (struct secasvar *);
107 static int ah_keyed_sha1_init (struct ah_algorithm_state *,
108         struct secasvar *);
109 static void ah_keyed_sha1_loop (struct ah_algorithm_state *, caddr_t,
110         size_t);
111 static void ah_keyed_sha1_result (struct ah_algorithm_state *, caddr_t);
112 static int ah_hmac_md5_mature (struct secasvar *);
113 static int ah_hmac_md5_init (struct ah_algorithm_state *,
114         struct secasvar *);
115 static void ah_hmac_md5_loop (struct ah_algorithm_state *, caddr_t,
116         size_t);
117 static void ah_hmac_md5_result (struct ah_algorithm_state *, caddr_t);
118 static int ah_hmac_sha1_mature (struct secasvar *);
119 static int ah_hmac_sha1_init (struct ah_algorithm_state *,
120         struct secasvar *);
121 static void ah_hmac_sha1_loop (struct ah_algorithm_state *, caddr_t,
122         size_t);
123 static void ah_hmac_sha1_result (struct ah_algorithm_state *, caddr_t);
124 static int ah_hmac_sha2_256_mature (struct secasvar *);
125 static int ah_hmac_sha2_256_init (struct ah_algorithm_state *,
126         struct secasvar *);
127 static void ah_hmac_sha2_256_loop (struct ah_algorithm_state *, caddr_t,
128         size_t);
129 static void ah_hmac_sha2_256_result (struct ah_algorithm_state *, caddr_t);
130 static int ah_hmac_sha2_384_mature (struct secasvar *);
131 static int ah_hmac_sha2_384_init (struct ah_algorithm_state *,
132         struct secasvar *);
133 static void ah_hmac_sha2_384_loop (struct ah_algorithm_state *, caddr_t,
134         size_t);
135 static void ah_hmac_sha2_384_result (struct ah_algorithm_state *, caddr_t);
136 static int ah_hmac_sha2_512_mature (struct secasvar *);
137 static int ah_hmac_sha2_512_init (struct ah_algorithm_state *,
138         struct secasvar *);
139 static void ah_hmac_sha2_512_loop (struct ah_algorithm_state *, caddr_t,
140         size_t);
141 static void ah_hmac_sha2_512_result (struct ah_algorithm_state *, caddr_t);
142
143 static void ah_update_mbuf (struct mbuf *, int, int,
144         const struct ah_algorithm *, struct ah_algorithm_state *);
145
146 const struct ah_algorithm *
147 ah_algorithm_lookup(int idx)
148 {
149         /* checksum algorithms */
150         static struct ah_algorithm ah_algorithms[] = {
151                 { ah_sumsiz_1216, ah_hmac_md5_mature, 128, 128, "hmac-md5",
152                         ah_hmac_md5_init, ah_hmac_md5_loop,
153                         ah_hmac_md5_result, },
154                 { ah_sumsiz_1216, ah_hmac_sha1_mature, 160, 160, "hmac-sha1",
155                         ah_hmac_sha1_init, ah_hmac_sha1_loop,
156                         ah_hmac_sha1_result, },
157                 { ah_sumsiz_1216, ah_keyed_md5_mature, 128, 128, "keyed-md5",
158                         ah_keyed_md5_init, ah_keyed_md5_loop,
159                         ah_keyed_md5_result, },
160                 { ah_sumsiz_1216, ah_keyed_sha1_mature, 160, 160, "keyed-sha1",
161                         ah_keyed_sha1_init, ah_keyed_sha1_loop,
162                         ah_keyed_sha1_result, },
163                 { ah_sumsiz_zero, ah_none_mature, 0, 2048, "none",
164                         ah_none_init, ah_none_loop, ah_none_result, },
165                 { ah_sumsiz_1216, ah_hmac_sha2_256_mature, 256, 256,
166                         "hmac-sha2-256",
167                         ah_hmac_sha2_256_init, ah_hmac_sha2_256_loop,
168                         ah_hmac_sha2_256_result, },
169                 { ah_sumsiz_1216, ah_hmac_sha2_384_mature, 384, 384,
170                         "hmac-sha2-384",
171                         ah_hmac_sha2_384_init, ah_hmac_sha2_384_loop,
172                         ah_hmac_sha2_384_result, },
173                 { ah_sumsiz_1216, ah_hmac_sha2_512_mature, 512, 512,
174                         "hmac-sha2-512",
175                         ah_hmac_sha2_512_init, ah_hmac_sha2_512_loop,
176                         ah_hmac_sha2_512_result, },
177         };
178
179         switch (idx) {
180         case SADB_AALG_MD5HMAC:
181                 return &ah_algorithms[0];
182         case SADB_AALG_SHA1HMAC:
183                 return &ah_algorithms[1];
184         case SADB_X_AALG_MD5:
185                 return &ah_algorithms[2];
186         case SADB_X_AALG_SHA:
187                 return &ah_algorithms[3];
188         case SADB_X_AALG_NULL:
189                 return &ah_algorithms[4];
190         case SADB_X_AALG_SHA2_256:
191                 return &ah_algorithms[5];
192         case SADB_X_AALG_SHA2_384:
193                 return &ah_algorithms[6];
194         case SADB_X_AALG_SHA2_512:
195                 return &ah_algorithms[7];
196         default:
197                 return NULL;
198         }
199 }
200
201
202 static int
203 ah_sumsiz_1216(struct secasvar *sav)
204 {
205         if (!sav)
206                 return -1;
207         if (sav->flags & SADB_X_EXT_OLD)
208                 return 16;
209         else
210                 return 12;
211 }
212
213 static int
214 ah_sumsiz_zero(struct secasvar *sav)
215 {
216         if (!sav)
217                 return -1;
218         return 0;
219 }
220
221 static int
222 ah_none_mature(struct secasvar *sav)
223 {
224         if (sav->sah->saidx.proto == IPPROTO_AH) {
225                 ipseclog((LOG_ERR,
226                     "ah_none_mature: protocol and algorithm mismatch.\n"));
227                 return 1;
228         }
229         return 0;
230 }
231
232 static int
233 ah_none_init(struct ah_algorithm_state *state, struct secasvar *sav)
234 {
235         state->foo = NULL;
236         return 0;
237 }
238
239 static void
240 ah_none_loop(struct ah_algorithm_state *state, caddr_t addr, size_t len)
241 {
242 }
243
244 static void
245 ah_none_result(struct ah_algorithm_state *state, caddr_t addr)
246 {
247 }
248
249 static int
250 ah_keyed_md5_mature(struct secasvar *sav)
251 {
252         /* anything is okay */
253         return 0;
254 }
255
256 static int
257 ah_keyed_md5_init(struct ah_algorithm_state *state, struct secasvar *sav)
258 {
259         size_t padlen;
260         size_t keybitlen;
261         u_int8_t buf[32];
262
263         if (!state)
264                 panic("ah_keyed_md5_init: what?");
265
266         state->sav = sav;
267         state->foo = (void *)kmalloc(sizeof(MD5_CTX), M_TEMP, M_NOWAIT);
268         if (state->foo == NULL)
269                 return ENOBUFS;
270
271         MD5Init((MD5_CTX *)state->foo);
272         if (state->sav) {
273                 MD5Update((MD5_CTX *)state->foo,
274                         (u_int8_t *)_KEYBUF(state->sav->key_auth),
275                         (u_int)_KEYLEN(state->sav->key_auth));
276
277                 /*
278                  * Pad after the key.
279                  * We cannot simply use md5_pad() since the function
280                  * won't update the total length.
281                  */
282                 if (_KEYLEN(state->sav->key_auth) < 56)
283                         padlen = 64 - 8 - _KEYLEN(state->sav->key_auth);
284                 else
285                         padlen = 64 + 64 - 8 - _KEYLEN(state->sav->key_auth);
286                 keybitlen = _KEYLEN(state->sav->key_auth);
287                 keybitlen *= 8;
288
289                 buf[0] = 0x80;
290                 MD5Update((MD5_CTX *)state->foo, &buf[0], 1);
291                 padlen--;
292
293                 bzero(buf, sizeof(buf));
294                 while (sizeof(buf) < padlen) {
295                         MD5Update((MD5_CTX *)state->foo, &buf[0], sizeof(buf));
296                         padlen -= sizeof(buf);
297                 }
298                 if (padlen) {
299                         MD5Update((MD5_CTX *)state->foo, &buf[0], padlen);
300                 }
301
302                 buf[0] = (keybitlen >> 0) & 0xff;
303                 buf[1] = (keybitlen >> 8) & 0xff;
304                 buf[2] = (keybitlen >> 16) & 0xff;
305                 buf[3] = (keybitlen >> 24) & 0xff;
306                 MD5Update((MD5_CTX *)state->foo, buf, 8);
307         }
308
309         return 0;
310 }
311
312 static void
313 ah_keyed_md5_loop(struct ah_algorithm_state *state, caddr_t addr, size_t len)
314 {
315         if (!state)
316                 panic("ah_keyed_md5_loop: what?");
317
318         MD5Update((MD5_CTX *)state->foo, addr, len);
319 }
320
321 static void
322 ah_keyed_md5_result(struct ah_algorithm_state *state, caddr_t addr)
323 {
324         u_char digest[16];
325
326         if (!state)
327                 panic("ah_keyed_md5_result: what?");
328
329         if (state->sav) {
330                 MD5Update((MD5_CTX *)state->foo,
331                         (u_int8_t *)_KEYBUF(state->sav->key_auth),
332                         (u_int)_KEYLEN(state->sav->key_auth));
333         }
334         MD5Final(&digest[0], (MD5_CTX *)state->foo);
335         kfree(state->foo, M_TEMP);
336         bcopy(&digest[0], (void *)addr, sizeof(digest));
337 }
338
339 static int
340 ah_keyed_sha1_mature(struct secasvar *sav)
341 {
342         const struct ah_algorithm *algo;
343
344         if (!sav->key_auth) {
345                 ipseclog((LOG_ERR, "ah_keyed_sha1_mature: no key is given.\n"));
346                 return 1;
347         }
348
349         algo = ah_algorithm_lookup(sav->alg_auth);
350         if (!algo) {
351                 ipseclog((LOG_ERR, "ah_keyed_sha1_mature: unsupported algorithm.\n"));
352                 return 1;
353         }
354
355         if (sav->key_auth->sadb_key_bits < algo->keymin
356          || algo->keymax < sav->key_auth->sadb_key_bits) {
357                 ipseclog((LOG_ERR,
358                     "ah_keyed_sha1_mature: invalid key length %d.\n",
359                     sav->key_auth->sadb_key_bits));
360                 return 1;
361         }
362
363         return 0;
364 }
365
366 static int
367 ah_keyed_sha1_init(struct ah_algorithm_state *state, struct secasvar *sav)
368 {
369         SHA1_CTX *ctxt;
370         size_t padlen;
371         size_t keybitlen;
372         u_int8_t buf[32];
373
374         if (!state)
375                 panic("ah_keyed_sha1_init: what?");
376
377         state->sav = sav;
378         state->foo = (void *)kmalloc(sizeof(SHA1_CTX), M_TEMP, M_NOWAIT);
379         if (!state->foo)
380                 return ENOBUFS;
381
382         ctxt = (SHA1_CTX *)state->foo;
383         SHA1Init(ctxt);
384
385         if (state->sav) {
386                 SHA1Update(ctxt, (u_int8_t *)_KEYBUF(state->sav->key_auth),
387                         (u_int)_KEYLEN(state->sav->key_auth));
388
389                 /*
390                  * Pad after the key.
391                  */
392                 if (_KEYLEN(state->sav->key_auth) < 56)
393                         padlen = 64 - 8 - _KEYLEN(state->sav->key_auth);
394                 else
395                         padlen = 64 + 64 - 8 - _KEYLEN(state->sav->key_auth);
396                 keybitlen = _KEYLEN(state->sav->key_auth);
397                 keybitlen *= 8;
398
399                 buf[0] = 0x80;
400                 SHA1Update(ctxt, &buf[0], 1);
401                 padlen--;
402
403                 bzero(buf, sizeof(buf));
404                 while (sizeof(buf) < padlen) {
405                         SHA1Update(ctxt, &buf[0], sizeof(buf));
406                         padlen -= sizeof(buf);
407                 }
408                 if (padlen) {
409                         SHA1Update(ctxt, &buf[0], padlen);
410                 }
411
412                 buf[0] = (keybitlen >> 0) & 0xff;
413                 buf[1] = (keybitlen >> 8) & 0xff;
414                 buf[2] = (keybitlen >> 16) & 0xff;
415                 buf[3] = (keybitlen >> 24) & 0xff;
416                 SHA1Update(ctxt, buf, 8);
417         }
418
419         return 0;
420 }
421
422 static void
423 ah_keyed_sha1_loop(struct ah_algorithm_state *state, caddr_t addr, size_t len)
424 {
425         SHA1_CTX *ctxt;
426
427         if (!state || !state->foo)
428                 panic("ah_keyed_sha1_loop: what?");
429         ctxt = (SHA1_CTX *)state->foo;
430
431         SHA1Update(ctxt, (caddr_t)addr, (size_t)len);
432 }
433
434 static void
435 ah_keyed_sha1_result(struct ah_algorithm_state *state, caddr_t addr)
436 {
437         u_char digest[SHA1_RESULTLEN];  /* SHA-1 generates 160 bits */
438         SHA1_CTX *ctxt;
439
440         if (!state || !state->foo)
441                 panic("ah_keyed_sha1_result: what?");
442         ctxt = (SHA1_CTX *)state->foo;
443
444         if (state->sav) {
445                 SHA1Update(ctxt, (u_int8_t *)_KEYBUF(state->sav->key_auth),
446                         (u_int)_KEYLEN(state->sav->key_auth));
447         }
448         SHA1Final((caddr_t)&digest[0], ctxt);
449         bcopy(&digest[0], (void *)addr, HMACSIZE);
450
451         kfree(state->foo, M_TEMP);
452 }
453
454 static int
455 ah_hmac_md5_mature(struct secasvar *sav)
456 {
457         const struct ah_algorithm *algo;
458
459         if (!sav->key_auth) {
460                 ipseclog((LOG_ERR, "ah_hmac_md5_mature: no key is given.\n"));
461                 return 1;
462         }
463
464         algo = ah_algorithm_lookup(sav->alg_auth);
465         if (!algo) {
466                 ipseclog((LOG_ERR, "ah_hmac_md5_mature: unsupported algorithm.\n"));
467                 return 1;
468         }
469
470         if (sav->key_auth->sadb_key_bits < algo->keymin
471          || algo->keymax < sav->key_auth->sadb_key_bits) {
472                 ipseclog((LOG_ERR,
473                     "ah_hmac_md5_mature: invalid key length %d.\n",
474                     sav->key_auth->sadb_key_bits));
475                 return 1;
476         }
477
478         return 0;
479 }
480
481 static int
482 ah_hmac_md5_init(struct ah_algorithm_state *state, struct secasvar *sav)
483 {
484         u_char *ipad;
485         u_char *opad;
486         u_char tk[16];
487         u_char *key;
488         size_t keylen;
489         size_t i;
490         MD5_CTX *ctxt;
491
492         if (!state)
493                 panic("ah_hmac_md5_init: what?");
494
495         state->sav = sav;
496         state->foo = (void *)kmalloc(64 + 64 + sizeof(MD5_CTX), M_TEMP, M_NOWAIT);
497         if (!state->foo)
498                 return ENOBUFS;
499
500         ipad = (u_char *)state->foo;
501         opad = (u_char *)(ipad + 64);
502         ctxt = (MD5_CTX *)(opad + 64);
503
504         /* compress the key if necessery */
505         if (64 < _KEYLEN(state->sav->key_auth)) {
506                 MD5Init(ctxt);
507                 MD5Update(ctxt, _KEYBUF(state->sav->key_auth),
508                         _KEYLEN(state->sav->key_auth));
509                 MD5Final(&tk[0], ctxt);
510                 key = &tk[0];
511                 keylen = 16;
512         } else {
513                 key = _KEYBUF(state->sav->key_auth);
514                 keylen = _KEYLEN(state->sav->key_auth);
515         }
516
517         bzero(ipad, 64);
518         bzero(opad, 64);
519         bcopy(key, ipad, keylen);
520         bcopy(key, opad, keylen);
521         for (i = 0; i < 64; i++) {
522                 ipad[i] ^= 0x36;
523                 opad[i] ^= 0x5c;
524         }
525
526         MD5Init(ctxt);
527         MD5Update(ctxt, ipad, 64);
528
529         return 0;
530 }
531
532 static void
533 ah_hmac_md5_loop(struct ah_algorithm_state *state, caddr_t addr, size_t len)
534 {
535         MD5_CTX *ctxt;
536
537         if (!state || !state->foo)
538                 panic("ah_hmac_md5_loop: what?");
539         ctxt = (MD5_CTX *)(((caddr_t)state->foo) + 128);
540         MD5Update(ctxt, addr, len);
541 }
542
543 static void
544 ah_hmac_md5_result(struct ah_algorithm_state *state, caddr_t addr)
545 {
546         u_char digest[16];
547         u_char *ipad;
548         u_char *opad;
549         MD5_CTX *ctxt;
550
551         if (!state || !state->foo)
552                 panic("ah_hmac_md5_result: what?");
553
554         ipad = (u_char *)state->foo;
555         opad = (u_char *)(ipad + 64);
556         ctxt = (MD5_CTX *)(opad + 64);
557
558         MD5Final(&digest[0], ctxt);
559
560         MD5Init(ctxt);
561         MD5Update(ctxt, opad, 64);
562         MD5Update(ctxt, &digest[0], sizeof(digest));
563         MD5Final(&digest[0], ctxt);
564
565         bcopy(&digest[0], (void *)addr, HMACSIZE);
566
567         kfree(state->foo, M_TEMP);
568 }
569
570 static int
571 ah_hmac_sha1_mature(struct secasvar *sav)
572 {
573         const struct ah_algorithm *algo;
574
575         if (!sav->key_auth) {
576                 ipseclog((LOG_ERR, "ah_hmac_sha1_mature: no key is given.\n"));
577                 return 1;
578         }
579
580         algo = ah_algorithm_lookup(sav->alg_auth);
581         if (!algo) {
582                 ipseclog((LOG_ERR, "ah_hmac_sha1_mature: unsupported algorithm.\n"));
583                 return 1;
584         }
585
586         if (sav->key_auth->sadb_key_bits < algo->keymin
587          || algo->keymax < sav->key_auth->sadb_key_bits) {
588                 ipseclog((LOG_ERR,
589                     "ah_hmac_sha1_mature: invalid key length %d.\n",
590                     sav->key_auth->sadb_key_bits));
591                 return 1;
592         }
593
594         return 0;
595 }
596
597 static int
598 ah_hmac_sha1_init(struct ah_algorithm_state *state, struct secasvar *sav)
599 {
600         u_char *ipad;
601         u_char *opad;
602         SHA1_CTX *ctxt;
603         u_char tk[SHA1_RESULTLEN];      /* SHA-1 generates 160 bits */
604         u_char *key;
605         size_t keylen;
606         size_t i;
607
608         if (!state)
609                 panic("ah_hmac_sha1_init: what?");
610
611         state->sav = sav;
612         state->foo = (void *)kmalloc(64 + 64 + sizeof(SHA1_CTX),
613                         M_TEMP, M_NOWAIT);
614         if (!state->foo)
615                 return ENOBUFS;
616
617         ipad = (u_char *)state->foo;
618         opad = (u_char *)(ipad + 64);
619         ctxt = (SHA1_CTX *)(opad + 64);
620
621         /* compress the key if necessery */
622         if (64 < _KEYLEN(state->sav->key_auth)) {
623                 SHA1Init(ctxt);
624                 SHA1Update(ctxt, _KEYBUF(state->sav->key_auth),
625                         _KEYLEN(state->sav->key_auth));
626                 SHA1Final(&tk[0], ctxt);
627                 key = &tk[0];
628                 keylen = SHA1_RESULTLEN;
629         } else {
630                 key = _KEYBUF(state->sav->key_auth);
631                 keylen = _KEYLEN(state->sav->key_auth);
632         }
633
634         bzero(ipad, 64);
635         bzero(opad, 64);
636         bcopy(key, ipad, keylen);
637         bcopy(key, opad, keylen);
638         for (i = 0; i < 64; i++) {
639                 ipad[i] ^= 0x36;
640                 opad[i] ^= 0x5c;
641         }
642
643         SHA1Init(ctxt);
644         SHA1Update(ctxt, ipad, 64);
645
646         return 0;
647 }
648
649 static void
650 ah_hmac_sha1_loop(struct ah_algorithm_state *state, caddr_t addr, size_t len)
651 {
652         SHA1_CTX *ctxt;
653
654         if (!state || !state->foo)
655                 panic("ah_hmac_sha1_loop: what?");
656
657         ctxt = (SHA1_CTX *)(((u_char *)state->foo) + 128);
658         SHA1Update(ctxt, (caddr_t)addr, (size_t)len);
659 }
660
661 static void
662 ah_hmac_sha1_result(struct ah_algorithm_state *state, caddr_t addr)
663 {
664         u_char digest[SHA1_RESULTLEN];  /* SHA-1 generates 160 bits */
665         u_char *ipad;
666         u_char *opad;
667         SHA1_CTX *ctxt;
668
669         if (!state || !state->foo)
670                 panic("ah_hmac_sha1_result: what?");
671
672         ipad = (u_char *)state->foo;
673         opad = (u_char *)(ipad + 64);
674         ctxt = (SHA1_CTX *)(opad + 64);
675
676         SHA1Final((caddr_t)&digest[0], ctxt);
677
678         SHA1Init(ctxt);
679         SHA1Update(ctxt, opad, 64);
680         SHA1Update(ctxt, (caddr_t)&digest[0], sizeof(digest));
681         SHA1Final((caddr_t)&digest[0], ctxt);
682
683         bcopy(&digest[0], (void *)addr, HMACSIZE);
684
685         kfree(state->foo, M_TEMP);
686 }
687
688 static int
689 ah_hmac_sha2_256_mature(struct secasvar *sav)
690 {
691         const struct ah_algorithm *algo;
692
693         if (!sav->key_auth) {
694                 ipseclog((LOG_ERR,
695                     "ah_hmac_sha2_256_mature: no key is given.\n"));
696                 return 1;
697         }
698
699         algo = ah_algorithm_lookup(sav->alg_auth);
700         if (!algo) {
701                 ipseclog((LOG_ERR,
702                     "ah_hmac_sha2_256_mature: unsupported algorithm.\n"));
703                 return 1;
704         }
705
706         if (sav->key_auth->sadb_key_bits < algo->keymin ||
707             algo->keymax < sav->key_auth->sadb_key_bits) {
708                 ipseclog((LOG_ERR,
709                     "ah_hmac_sha2_256_mature: invalid key length %d.\n",
710                     sav->key_auth->sadb_key_bits));
711                 return 1;
712         }
713
714         return 0;
715 }
716
717 static int
718 ah_hmac_sha2_256_init(struct ah_algorithm_state *state, struct secasvar *sav)
719 {
720         u_char *ipad;
721         u_char *opad;
722         SHA256_CTX *ctxt;
723         u_char tk[SHA256_DIGEST_LENGTH];
724         u_char *key;
725         size_t keylen;
726         size_t i;
727
728         if (!state)
729                 panic("ah_hmac_sha2_256_init: what?");
730
731         state->sav = sav;
732         state->foo = (void *)kmalloc(64 + 64 + sizeof(SHA256_CTX),
733             M_TEMP, M_NOWAIT);
734         if (!state->foo)
735                 return ENOBUFS;
736
737         ipad = (u_char *)state->foo;
738         opad = (u_char *)(ipad + 64);
739         ctxt = (SHA256_CTX *)(opad + 64);
740
741         /* compress the key if necessery */
742         if (64 < _KEYLEN(state->sav->key_auth)) {
743                 bzero(tk, sizeof(tk));
744                 bzero(ctxt, sizeof(*ctxt));
745                 SHA256_Init(ctxt);
746                 SHA256_Update(ctxt, _KEYBUF(state->sav->key_auth),
747                     _KEYLEN(state->sav->key_auth));
748                 SHA256_Final(&tk[0], ctxt);
749                 key = &tk[0];
750                 keylen = sizeof(tk) < 64 ? sizeof(tk) : 64;
751         } else {
752                 key = _KEYBUF(state->sav->key_auth);
753                 keylen = _KEYLEN(state->sav->key_auth);
754         }
755
756         bzero(ipad, 64);
757         bzero(opad, 64);
758         bcopy(key, ipad, keylen);
759         bcopy(key, opad, keylen);
760         for (i = 0; i < 64; i++) {
761                 ipad[i] ^= 0x36;
762                 opad[i] ^= 0x5c;
763         }
764
765         bzero(ctxt, sizeof(*ctxt));
766         SHA256_Init(ctxt);
767         SHA256_Update(ctxt, ipad, 64);
768
769         return 0;
770 }
771
772 static void
773 ah_hmac_sha2_256_loop(struct ah_algorithm_state *state, caddr_t addr, size_t
774                       len)
775 {
776         SHA256_CTX *ctxt;
777
778         if (!state || !state->foo)
779                 panic("ah_hmac_sha2_256_loop: what?");
780
781         ctxt = (SHA256_CTX *)(((u_char *)state->foo) + 128);
782         SHA256_Update(ctxt, (caddr_t)addr, (size_t)len);
783 }
784
785 static void
786 ah_hmac_sha2_256_result(struct ah_algorithm_state *state, caddr_t addr)
787 {
788         u_char digest[SHA256_DIGEST_LENGTH];
789         u_char *ipad;
790         u_char *opad;
791         SHA256_CTX *ctxt;
792
793         if (!state || !state->foo)
794                 panic("ah_hmac_sha2_256_result: what?");
795
796         ipad = (u_char *)state->foo;
797         opad = (u_char *)(ipad + 64);
798         ctxt = (SHA256_CTX *)(opad + 64);
799
800         SHA256_Final((caddr_t)&digest[0], ctxt);
801
802         bzero(ctxt, sizeof(*ctxt));
803         SHA256_Init(ctxt);
804         SHA256_Update(ctxt, opad, 64);
805         SHA256_Update(ctxt, (caddr_t)&digest[0], sizeof(digest));
806         SHA256_Final((caddr_t)&digest[0], ctxt);
807
808         bcopy(&digest[0], (void *)addr, HMACSIZE);
809
810         kfree(state->foo, M_TEMP);
811 }
812
813 static int
814 ah_hmac_sha2_384_mature(struct secasvar *sav)
815 {
816         const struct ah_algorithm *algo;
817
818         if (!sav->key_auth) {
819                 ipseclog((LOG_ERR,
820                     "ah_hmac_sha2_384_mature: no key is given.\n"));
821                 return 1;
822         }
823
824         algo = ah_algorithm_lookup(sav->alg_auth);
825         if (!algo) {
826                 ipseclog((LOG_ERR,
827                     "ah_hmac_sha2_384_mature: unsupported algorithm.\n"));
828                 return 1;
829         }
830
831         if (sav->key_auth->sadb_key_bits < algo->keymin ||
832             algo->keymax < sav->key_auth->sadb_key_bits) {
833                 ipseclog((LOG_ERR,
834                     "ah_hmac_sha2_384_mature: invalid key length %d.\n",
835                     sav->key_auth->sadb_key_bits));
836                 return 1;
837         }
838
839         return 0;
840 }
841
842 static int
843 ah_hmac_sha2_384_init(struct ah_algorithm_state *state, struct secasvar *sav)
844 {
845         u_char *ipad;
846         u_char *opad;
847         SHA384_CTX *ctxt;
848         u_char tk[SHA384_DIGEST_LENGTH];
849         u_char *key;
850         size_t keylen;
851         size_t i;
852
853         if (!state)
854                 panic("ah_hmac_sha2_384_init: what?");
855
856         state->sav = sav;
857         state->foo = (void *)kmalloc(64 + 64 + sizeof(SHA384_CTX),
858             M_TEMP, M_NOWAIT | M_ZERO);
859         if (!state->foo)
860                 return ENOBUFS;
861
862         ipad = (u_char *)state->foo;
863         opad = (u_char *)(ipad + 64);
864         ctxt = (SHA384_CTX *)(opad + 64);
865
866         /* compress the key if necessery */
867         if (64 < _KEYLEN(state->sav->key_auth)) {
868                 bzero(tk, sizeof(tk));
869                 bzero(ctxt, sizeof(*ctxt));
870                 SHA384_Init(ctxt);
871                 SHA384_Update(ctxt, _KEYBUF(state->sav->key_auth),
872                     _KEYLEN(state->sav->key_auth));
873                 SHA384_Final(&tk[0], ctxt);
874                 key = &tk[0];
875                 keylen = sizeof(tk) < 64 ? sizeof(tk) : 64;
876         } else {
877                 key = _KEYBUF(state->sav->key_auth);
878                 keylen = _KEYLEN(state->sav->key_auth);
879         }
880
881         bzero(ipad, 64);
882         bzero(opad, 64);
883         bcopy(key, ipad, keylen);
884         bcopy(key, opad, keylen);
885         for (i = 0; i < 64; i++) {
886                 ipad[i] ^= 0x36;
887                 opad[i] ^= 0x5c;
888         }
889
890         bzero(ctxt, sizeof(*ctxt));
891         SHA384_Init(ctxt);
892         SHA384_Update(ctxt, ipad, 64);
893
894         return 0;
895 }
896
897 static void
898 ah_hmac_sha2_384_loop(struct ah_algorithm_state *state, caddr_t addr,
899                       size_t len)
900 {
901         SHA384_CTX *ctxt;
902
903         if (!state || !state->foo)
904                 panic("ah_hmac_sha2_384_loop: what?");
905
906         ctxt = (SHA384_CTX *)(((u_char *)state->foo) + 128);
907         SHA384_Update(ctxt, (caddr_t)addr, (size_t)len);
908 }
909
910 static void
911 ah_hmac_sha2_384_result(struct ah_algorithm_state *state, caddr_t addr)
912 {
913         u_char digest[SHA384_DIGEST_LENGTH];
914         u_char *ipad;
915         u_char *opad;
916         SHA384_CTX *ctxt;
917
918         if (!state || !state->foo)
919                 panic("ah_hmac_sha2_384_result: what?");
920
921         ipad = (u_char *)state->foo;
922         opad = (u_char *)(ipad + 64);
923         ctxt = (SHA384_CTX *)(opad + 64);
924
925         SHA384_Final((caddr_t)&digest[0], ctxt);
926
927         bzero(ctxt, sizeof(*ctxt));
928         SHA384_Init(ctxt);
929         SHA384_Update(ctxt, opad, 64);
930         SHA384_Update(ctxt, (caddr_t)&digest[0], sizeof(digest));
931         SHA384_Final((caddr_t)&digest[0], ctxt);
932
933         bcopy(&digest[0], (void *)addr, HMACSIZE);
934
935         kfree(state->foo, M_TEMP);
936 }
937
938 static int
939 ah_hmac_sha2_512_mature(struct secasvar *sav)
940 {
941         const struct ah_algorithm *algo;
942
943         if (!sav->key_auth) {
944                 ipseclog((LOG_ERR,
945                     "ah_hmac_sha2_512_mature: no key is given.\n"));
946                 return 1;
947         }
948
949         algo = ah_algorithm_lookup(sav->alg_auth);
950         if (!algo) {
951                 ipseclog((LOG_ERR,
952                     "ah_hmac_sha2_512_mature: unsupported algorithm.\n"));
953                 return 1;
954         }
955
956         if (sav->key_auth->sadb_key_bits < algo->keymin ||
957             algo->keymax < sav->key_auth->sadb_key_bits) {
958                 ipseclog((LOG_ERR,
959                     "ah_hmac_sha2_512_mature: invalid key length %d.\n",
960                     sav->key_auth->sadb_key_bits));
961                 return 1;
962         }
963
964         return 0;
965 }
966
967 static int
968 ah_hmac_sha2_512_init(struct ah_algorithm_state *state, struct secasvar *sav)
969 {
970         u_char *ipad;
971         u_char *opad;
972         SHA512_CTX *ctxt;
973         u_char tk[SHA512_DIGEST_LENGTH];
974         u_char *key;
975         size_t keylen;
976         size_t i;
977
978         if (!state)
979                 panic("ah_hmac_sha2_512_init: what?");
980
981         state->sav = sav;
982         state->foo = (void *)kmalloc(64 + 64 + sizeof(SHA512_CTX),
983             M_TEMP, M_NOWAIT | M_ZERO);
984         if (!state->foo)
985                 return ENOBUFS;
986
987         ipad = (u_char *)state->foo;
988         opad = (u_char *)(ipad + 64);
989         ctxt = (SHA512_CTX *)(opad + 64);
990
991         /* compress the key if necessery */
992         if (64 < _KEYLEN(state->sav->key_auth)) {
993                 bzero(tk, sizeof(tk));
994                 bzero(ctxt, sizeof(*ctxt));
995                 SHA512_Init(ctxt);
996                 SHA512_Update(ctxt, _KEYBUF(state->sav->key_auth),
997                     _KEYLEN(state->sav->key_auth));
998                 SHA512_Final(&tk[0], ctxt);
999                 key = &tk[0];
1000                 keylen = sizeof(tk) < 64 ? sizeof(tk) : 64;
1001         } else {
1002                 key = _KEYBUF(state->sav->key_auth);
1003                 keylen = _KEYLEN(state->sav->key_auth);
1004         }
1005
1006         bzero(ipad, 64);
1007         bzero(opad, 64);
1008         bcopy(key, ipad, keylen);
1009         bcopy(key, opad, keylen);
1010         for (i = 0; i < 64; i++) {
1011                 ipad[i] ^= 0x36;
1012                 opad[i] ^= 0x5c;
1013         }
1014
1015         bzero(ctxt, sizeof(*ctxt));
1016         SHA512_Init(ctxt);
1017         SHA512_Update(ctxt, ipad, 64);
1018
1019         return 0;
1020 }
1021
1022 static void
1023 ah_hmac_sha2_512_loop(struct ah_algorithm_state *state, caddr_t addr,
1024                       size_t len)
1025 {
1026         SHA512_CTX *ctxt;
1027
1028         if (!state || !state->foo)
1029                 panic("ah_hmac_sha2_512_loop: what?");
1030
1031         ctxt = (SHA512_CTX *)(((u_char *)state->foo) + 128);
1032         SHA512_Update(ctxt, (caddr_t)addr, (size_t)len);
1033 }
1034
1035 static void
1036 ah_hmac_sha2_512_result(struct ah_algorithm_state *state, caddr_t addr)
1037 {
1038         u_char digest[SHA512_DIGEST_LENGTH];
1039         u_char *ipad;
1040         u_char *opad;
1041         SHA512_CTX *ctxt;
1042
1043         if (!state || !state->foo)
1044                 panic("ah_hmac_sha2_512_result: what?");
1045
1046         ipad = (u_char *)state->foo;
1047         opad = (u_char *)(ipad + 64);
1048         ctxt = (SHA512_CTX *)(opad + 64);
1049
1050         SHA512_Final((caddr_t)&digest[0], ctxt);
1051
1052         bzero(ctxt, sizeof(*ctxt));
1053         SHA512_Init(ctxt);
1054         SHA512_Update(ctxt, opad, 64);
1055         SHA512_Update(ctxt, (caddr_t)&digest[0], sizeof(digest));
1056         SHA512_Final((caddr_t)&digest[0], ctxt);
1057
1058         bcopy(&digest[0], (void *)addr, HMACSIZE);
1059
1060         kfree(state->foo, M_TEMP);
1061 }
1062
1063 /*------------------------------------------------------------*/
1064
1065 /*
1066  * go generate the checksum.
1067  */
1068 static void
1069 ah_update_mbuf(struct mbuf *m, int off, int len,
1070                const struct ah_algorithm *algo,
1071                struct ah_algorithm_state *algos)
1072 {
1073         struct mbuf *n;
1074         int tlen;
1075
1076         /* easy case first */
1077         if (off + len <= m->m_len) {
1078                 (algo->update)(algos, mtod(m, caddr_t) + off, len);
1079                 return;
1080         }
1081
1082         for (n = m; n; n = n->m_next) {
1083                 if (off < n->m_len)
1084                         break;
1085
1086                 off -= n->m_len;
1087         }
1088
1089         if (!n)
1090                 panic("ah_update_mbuf: wrong offset specified");
1091
1092         for (/* nothing */; n && len > 0; n = n->m_next) {
1093                 if (n->m_len == 0)
1094                         continue;
1095                 if (n->m_len - off < len)
1096                         tlen = n->m_len - off;
1097                 else
1098                         tlen = len;
1099
1100                 (algo->update)(algos, mtod(n, caddr_t) + off, tlen);
1101
1102                 len -= tlen;
1103                 off = 0;
1104         }
1105 }
1106
1107 #ifdef INET
1108 /*
1109  * Go generate the checksum. This function won't modify the mbuf chain
1110  * except AH itself.
1111  *
1112  * NOTE: the function does not free mbuf on failure.
1113  * Don't use m_copy(), it will try to share cluster mbuf by using refcnt.
1114  */
1115 int
1116 ah4_calccksum(struct mbuf *m, caddr_t ahdat, size_t len,
1117               const struct ah_algorithm *algo, struct secasvar *sav)
1118 {
1119         int off;
1120         int hdrtype;
1121         size_t advancewidth;
1122         struct ah_algorithm_state algos;
1123         u_char sumbuf[AH_MAXSUMSIZE];
1124         int error = 0;
1125         int ahseen;
1126         struct mbuf *n = NULL;
1127
1128         if ((m->m_flags & M_PKTHDR) == 0)
1129                 return EINVAL;
1130
1131         ahseen = 0;
1132         hdrtype = -1;   /* dummy, it is called IPPROTO_IP */
1133
1134         off = 0;
1135
1136         error = (algo->init)(&algos, sav);
1137         if (error)
1138                 return error;
1139
1140         advancewidth = 0;       /* safety */
1141
1142 again:
1143         /* gory. */
1144         switch (hdrtype) {
1145         case -1:        /* first one only */
1146             {
1147                 /*
1148                  * copy ip hdr, modify to fit the AH checksum rule,
1149                  * then take a checksum.
1150                  */
1151                 struct ip iphdr;
1152                 size_t hlen;
1153
1154                 m_copydata(m, off, sizeof(iphdr), (caddr_t)&iphdr);
1155 #ifdef _IP_VHL
1156                 hlen = IP_VHL_HL(iphdr.ip_vhl) << 2;
1157 #else
1158                 hlen = iphdr.ip_hl << 2;
1159 #endif
1160                 iphdr.ip_ttl = 0;
1161                 iphdr.ip_sum = htons(0);
1162                 if (ip4_ah_cleartos)
1163                         iphdr.ip_tos = 0;
1164                 iphdr.ip_off = htons(ntohs(iphdr.ip_off) & ip4_ah_offsetmask);
1165                 (algo->update)(&algos, (caddr_t)&iphdr, sizeof(struct ip));
1166
1167                 if (hlen != sizeof(struct ip)) {
1168                         u_char *p;
1169                         int i, l, skip;
1170
1171                         if (hlen > MCLBYTES) {
1172                                 error = EMSGSIZE;
1173                                 goto fail;
1174                         }
1175                         n = m_getb(hlen, MB_DONTWAIT, MT_DATA, 0);
1176                         if (n == NULL) {
1177                                 error = ENOBUFS;
1178                                 goto fail;
1179                         }
1180                         m_copydata(m, off, hlen, mtod(n, caddr_t));
1181
1182                         /*
1183                          * IP options processing.
1184                          * See RFC2402 appendix A.
1185                          */
1186                         p = mtod(n, u_char *);
1187                         i = sizeof(struct ip);
1188                         while (i < hlen) {
1189                                 if (i + IPOPT_OPTVAL >= hlen) {
1190                                         ipseclog((LOG_ERR, "ah4_calccksum: "
1191                                             "invalid IP option\n"));
1192                                         error = EINVAL;
1193                                         goto fail;
1194                                 }
1195                                 if (p[i + IPOPT_OPTVAL] == IPOPT_EOL ||
1196                                     p[i + IPOPT_OPTVAL] == IPOPT_NOP ||
1197                                     i + IPOPT_OLEN < hlen)
1198                                         ;
1199                                 else {
1200                                         ipseclog((LOG_ERR,
1201                                             "ah4_calccksum: invalid IP option "
1202                                             "(type=%02x)\n",
1203                                             p[i + IPOPT_OPTVAL]));
1204                                         error = EINVAL;
1205                                         goto fail;
1206                                 }
1207
1208                                 skip = 1;
1209                                 switch (p[i + IPOPT_OPTVAL]) {
1210                                 case IPOPT_EOL:
1211                                 case IPOPT_NOP:
1212                                         l = 1;
1213                                         skip = 0;
1214                                         break;
1215                                 case IPOPT_SECURITY:    /* 0x82 */
1216                                 case 0x85:      /* Extended security */
1217                                 case 0x86:      /* Commercial security */
1218                                 case 0x94:      /* Router alert */
1219                                 case 0x95:      /* RFC1770 */
1220                                         l = p[i + IPOPT_OLEN];
1221                                         if (l < 2)
1222                                                 goto invalopt;
1223                                         skip = 0;
1224                                         break;
1225                                 default:
1226                                         l = p[i + IPOPT_OLEN];
1227                                         if (l < 2)
1228                                                 goto invalopt;
1229                                         skip = 1;
1230                                         break;
1231                                 }
1232                                 if (l < 1 || hlen - i < l) {
1233                         invalopt:
1234                                         ipseclog((LOG_ERR,
1235                                             "ah4_calccksum: invalid IP option "
1236                                             "(type=%02x len=%02x)\n",
1237                                             p[i + IPOPT_OPTVAL],
1238                                             p[i + IPOPT_OLEN]));
1239                                         error = EINVAL;
1240                                         goto fail;
1241                                 }
1242                                 if (skip)
1243                                         bzero(p + i, l);
1244                                 if (p[i + IPOPT_OPTVAL] == IPOPT_EOL)
1245                                         break;
1246                                 i += l;
1247                         }
1248                         p = mtod(n, u_char *) + sizeof(struct ip);
1249                         (algo->update)(&algos, p, hlen - sizeof(struct ip));
1250
1251                         m_free(n);
1252                         n = NULL;
1253                 }
1254
1255                 hdrtype = (iphdr.ip_p) & 0xff;
1256                 advancewidth = hlen;
1257                 break;
1258             }
1259
1260         case IPPROTO_AH:
1261             {
1262                 struct ah ah;
1263                 int siz;
1264                 int hdrsiz;
1265                 int totlen;
1266
1267                 m_copydata(m, off, sizeof(ah), (caddr_t)&ah);
1268                 hdrsiz = (sav->flags & SADB_X_EXT_OLD)
1269                                 ? sizeof(struct ah)
1270                                 : sizeof(struct newah);
1271                 siz = (*algo->sumsiz)(sav);
1272                 totlen = (ah.ah_len + 2) << 2;
1273
1274                 /*
1275                  * special treatment is necessary for the first one, not others
1276                  */
1277                 if (!ahseen) {
1278                         if (totlen > m->m_pkthdr.len - off ||
1279                             totlen > MCLBYTES) {
1280                                 error = EMSGSIZE;
1281                                 goto fail;
1282                         }
1283                         n = m_getb(totlen, MB_DONTWAIT, MT_DATA, 0);
1284                         if (n == NULL) {
1285                                 error = ENOBUFS;
1286                                 goto fail;
1287                         }
1288                         m_copydata(m, off, totlen, mtod(n, caddr_t));
1289                         n->m_len = totlen;
1290                         bzero(mtod(n, caddr_t) + hdrsiz, siz);
1291                         (algo->update)(&algos, mtod(n, caddr_t), n->m_len);
1292                         m_free(n);
1293                         n = NULL;
1294                 } else
1295                         ah_update_mbuf(m, off, totlen, algo, &algos);
1296                 ahseen++;
1297
1298                 hdrtype = ah.ah_nxt;
1299                 advancewidth = totlen;
1300                 break;
1301             }
1302
1303         default:
1304                 ah_update_mbuf(m, off, m->m_pkthdr.len - off, algo, &algos);
1305                 advancewidth = m->m_pkthdr.len - off;
1306                 break;
1307         }
1308
1309         off += advancewidth;
1310         if (off < m->m_pkthdr.len)
1311                 goto again;
1312
1313         if (len < (*algo->sumsiz)(sav)) {
1314                 error = EINVAL;
1315                 goto fail;
1316         }
1317
1318         (algo->result)(&algos, &sumbuf[0]);
1319         bcopy(&sumbuf[0], ahdat, (*algo->sumsiz)(sav));
1320
1321         if (n)
1322                 m_free(n);
1323         return error;
1324
1325 fail:
1326         if (n)
1327                 m_free(n);
1328         return error;
1329 }
1330 #endif
1331
1332 #ifdef INET6
1333 /*
1334  * Go generate the checksum. This function won't modify the mbuf chain
1335  * except AH itself.
1336  *
1337  * NOTE: the function does not free mbuf on failure.
1338  * Don't use m_copy(), it will try to share cluster mbuf by using refcnt.
1339  */
1340 int
1341 ah6_calccksum(struct mbuf *m, caddr_t ahdat, size_t len,
1342               const struct ah_algorithm *algo, struct secasvar *sav)
1343 {
1344         int newoff, off;
1345         int proto, nxt;
1346         struct mbuf *n = NULL;
1347         int error;
1348         int ahseen;
1349         struct ah_algorithm_state algos;
1350         u_char sumbuf[AH_MAXSUMSIZE];
1351
1352         if ((m->m_flags & M_PKTHDR) == 0)
1353                 return EINVAL;
1354
1355         error = (algo->init)(&algos, sav);
1356         if (error)
1357                 return error;
1358
1359         off = 0;
1360         proto = IPPROTO_IPV6;
1361         nxt = -1;
1362         ahseen = 0;
1363
1364 again:
1365         newoff = ip6_nexthdr(m, off, proto, &nxt);
1366         if (newoff < 0)
1367                 newoff = m->m_pkthdr.len;
1368         else if (newoff <= off) {
1369                 error = EINVAL;
1370                 goto fail;
1371         }
1372
1373         switch (proto) {
1374         case IPPROTO_IPV6:
1375                 /*
1376                  * special treatment is necessary for the first one, not others
1377                  */
1378                 if (off == 0) {
1379                         struct ip6_hdr ip6copy;
1380
1381                         if (newoff - off != sizeof(struct ip6_hdr)) {
1382                                 error = EINVAL;
1383                                 goto fail;
1384                         }
1385
1386                         m_copydata(m, off, newoff - off, (caddr_t)&ip6copy);
1387                         /* RFC2402 */
1388                         ip6copy.ip6_flow = 0;
1389                         ip6copy.ip6_vfc &= ~IPV6_VERSION_MASK;
1390                         ip6copy.ip6_vfc |= IPV6_VERSION;
1391                         ip6copy.ip6_hlim = 0;
1392                         if (IN6_IS_ADDR_LINKLOCAL(&ip6copy.ip6_src))
1393                                 ip6copy.ip6_src.s6_addr16[1] = 0x0000;
1394                         if (IN6_IS_ADDR_LINKLOCAL(&ip6copy.ip6_dst))
1395                                 ip6copy.ip6_dst.s6_addr16[1] = 0x0000;
1396                         (algo->update)(&algos, (caddr_t)&ip6copy,
1397                                        sizeof(struct ip6_hdr));
1398                 } else {
1399                         newoff = m->m_pkthdr.len;
1400                         ah_update_mbuf(m, off, m->m_pkthdr.len - off, algo,
1401                             &algos);
1402                 }
1403                 break;
1404
1405         case IPPROTO_AH:
1406             {
1407                 int siz;
1408                 int hdrsiz;
1409
1410                 hdrsiz = (sav->flags & SADB_X_EXT_OLD)
1411                                 ? sizeof(struct ah)
1412                                 : sizeof(struct newah);
1413                 siz = (*algo->sumsiz)(sav);
1414
1415                 /*
1416                  * special treatment is necessary for the first one, not others
1417                  */
1418                 if (!ahseen) {
1419                         if (newoff - off > MCLBYTES) {
1420                                 error = EMSGSIZE;
1421                                 goto fail;
1422                         }
1423                         n = m_getb(newoff - off, MB_DONTWAIT, MT_DATA, 0);
1424                         if (n == NULL) {
1425                                 error = ENOBUFS;
1426                                 goto fail;
1427                         }
1428                         m_copydata(m, off, newoff - off, mtod(n, caddr_t));
1429                         n->m_len = newoff - off;
1430                         bzero(mtod(n, caddr_t) + hdrsiz, siz);
1431                         (algo->update)(&algos, mtod(n, caddr_t), n->m_len);
1432                         m_free(n);
1433                         n = NULL;
1434                 } else
1435                         ah_update_mbuf(m, off, newoff - off, algo, &algos);
1436                 ahseen++;
1437                 break;
1438             }
1439
1440          case IPPROTO_HOPOPTS:
1441          case IPPROTO_DSTOPTS:
1442          {
1443                 struct ip6_ext *ip6e;
1444                 int hdrlen, optlen;
1445                 u_int8_t *p, *optend, *optp;
1446
1447                 if (newoff - off > MCLBYTES) {
1448                         error = EMSGSIZE;
1449                         goto fail;
1450                 }
1451                 n = m_getb(newoff - off, MB_DONTWAIT, MT_DATA, 0);
1452                 if (n == NULL) {
1453                         error = ENOBUFS;
1454                         goto fail;
1455                 }
1456                 m_copydata(m, off, newoff - off, mtod(n, caddr_t));
1457                 n->m_len = newoff - off;
1458
1459                 ip6e = mtod(n, struct ip6_ext *);
1460                 hdrlen = (ip6e->ip6e_len + 1) << 3;
1461                 if (newoff - off < hdrlen) {
1462                          error = EINVAL;
1463                          m_free(n);
1464                          n = NULL;
1465                          goto fail;
1466                 }
1467                 p = mtod(n, u_int8_t *);
1468                 optend = p + hdrlen;
1469
1470                 /*
1471                  * ICV calculation for the options header including all
1472                  * options.  This part is a little tricky since there are
1473                  * two type of options; mutable and immutable.  We try to
1474                  * null-out mutable ones here.
1475                  */
1476                 optp = p + 2;
1477                 while (optp < optend) {
1478                         if (optp[0] == IP6OPT_PAD1)
1479                                 optlen = 1;
1480                         else {
1481                                 if (optp + 2 > optend) {
1482                                         error = EINVAL;
1483                                         m_free(n);
1484                                         n = NULL;
1485                                         goto fail;
1486                                 }
1487                                 optlen = optp[1] + 2;
1488
1489                                 if (optp[0] & IP6OPT_MUTABLE)
1490                                         bzero(optp + 2, optlen - 2);
1491                         }
1492
1493                         optp += optlen;
1494                 }
1495
1496                 (algo->update)(&algos, mtod(n, caddr_t), n->m_len);
1497                 m_free(n);
1498                 n = NULL;
1499                 break;
1500          }
1501
1502          case IPPROTO_ROUTING:
1503                 /*
1504                  * For an input packet, we can just calculate `as is'.
1505                  * For an output packet, we assume ip6_output have already
1506                  * made packet how it will be received at the final
1507                  * destination.
1508                  */
1509                 /* FALLTHROUGH */
1510
1511         default:
1512                 ah_update_mbuf(m, off, newoff - off, algo, &algos);
1513                 break;
1514         }
1515
1516         if (newoff < m->m_pkthdr.len) {
1517                 proto = nxt;
1518                 off = newoff;
1519                 goto again;
1520         }
1521
1522         if (len < (*algo->sumsiz)(sav)) {
1523                 error = EINVAL;
1524                 goto fail;
1525         }
1526
1527         (algo->result)(&algos, &sumbuf[0]);
1528         bcopy(&sumbuf[0], ahdat, (*algo->sumsiz)(sav));
1529
1530         /* just in case */
1531         if (n)
1532                 m_free(n);
1533         return 0;
1534 fail:
1535         /* just in case */
1536         if (n)
1537                 m_free(n);
1538         return error;
1539 }
1540 #endif