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