2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the project nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * RFC1826/2402 authentication header.
34 #if (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(__NetBSD__)
36 #if __NetBSD__ /*XXX*/
37 #include "opt_ipsec.h"
41 /* Some of operating systems have standard crypto checksum library */
46 #if defined(__FreeBSD__) || defined(__APPLE__)
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/malloc.h>
54 #include <sys/domain.h>
55 #include <sys/protosw.h>
56 #include <sys/socket.h>
57 #include <sys/socketvar.h>
58 #include <sys/errno.h>
60 #include <sys/kernel.h>
61 #include <sys/syslog.h>
64 #include <net/route.h>
66 #include <netinet/in.h>
67 #include <netinet/in_systm.h>
68 #include <netinet/ip.h>
69 #include <netinet/in_var.h>
72 #include <netinet/ip6.h>
73 #include <netinet6/ip6_var.h>
74 #include <netinet/icmp6.h>
77 #include <netinet6/ipsec.h>
78 #include <netinet6/ah.h>
80 #include <netinet6/esp.h>
82 #include <net/pfkeyv2.h>
83 #include <netkey/keydb.h>
87 #include <crypto/md5.h>
91 #define SHA1_RESULTLEN 20
93 #include <crypto/sha1.h>
96 #include <net/net_osdep.h>
100 static int ah_sumsiz_1216
__P((struct secasvar
*));
101 static int ah_sumsiz_zero
__P((struct secasvar
*));
102 static int ah_none_mature
__P((struct secasvar
*));
103 static void ah_none_init
__P((struct ah_algorithm_state
*,
105 static void ah_none_loop
__P((struct ah_algorithm_state
*, caddr_t
, size_t));
106 static void ah_none_result
__P((struct ah_algorithm_state
*, caddr_t
));
107 static int ah_keyed_md5_mature
__P((struct secasvar
*));
108 static void ah_keyed_md5_init
__P((struct ah_algorithm_state
*,
110 static void ah_keyed_md5_loop
__P((struct ah_algorithm_state
*, caddr_t
,
112 static void ah_keyed_md5_result
__P((struct ah_algorithm_state
*, caddr_t
));
113 static int ah_keyed_sha1_mature
__P((struct secasvar
*));
114 static void ah_keyed_sha1_init
__P((struct ah_algorithm_state
*,
116 static void ah_keyed_sha1_loop
__P((struct ah_algorithm_state
*, caddr_t
,
118 static void ah_keyed_sha1_result
__P((struct ah_algorithm_state
*, caddr_t
));
119 static int ah_hmac_md5_mature
__P((struct secasvar
*));
120 static void ah_hmac_md5_init
__P((struct ah_algorithm_state
*,
122 static void ah_hmac_md5_loop
__P((struct ah_algorithm_state
*, caddr_t
,
124 static void ah_hmac_md5_result
__P((struct ah_algorithm_state
*, caddr_t
));
125 static int ah_hmac_sha1_mature
__P((struct secasvar
*));
126 static void ah_hmac_sha1_init
__P((struct ah_algorithm_state
*,
128 static void ah_hmac_sha1_loop
__P((struct ah_algorithm_state
*, caddr_t
,
130 static void ah_hmac_sha1_result
__P((struct ah_algorithm_state
*, caddr_t
));
132 static void ah_update_mbuf
__P((struct mbuf
*, int, int, struct ah_algorithm
*,
133 struct ah_algorithm_state
*));
135 /* checksum algorithms */
136 /* NOTE: The order depends on SADB_AALG_x in net/pfkeyv2.h */
137 struct ah_algorithm ah_algorithms
[] = {
138 { 0, 0, 0, 0, 0, 0, },
139 { ah_sumsiz_1216
, ah_hmac_md5_mature
, 128, 128,
140 ah_hmac_md5_init
, ah_hmac_md5_loop
, ah_hmac_md5_result
, },
141 { ah_sumsiz_1216
, ah_hmac_sha1_mature
, 160, 160,
142 ah_hmac_sha1_init
, ah_hmac_sha1_loop
, ah_hmac_sha1_result
, },
143 { ah_sumsiz_1216
, ah_keyed_md5_mature
, 128, 128,
144 ah_keyed_md5_init
, ah_keyed_md5_loop
, ah_keyed_md5_result
, },
145 { ah_sumsiz_1216
, ah_keyed_sha1_mature
, 160, 160,
146 ah_keyed_sha1_init
, ah_keyed_sha1_loop
, ah_keyed_sha1_result
, },
147 { ah_sumsiz_zero
, ah_none_mature
, 0, 2048,
148 ah_none_init
, ah_none_loop
, ah_none_result
, },
153 struct secasvar
*sav
;
157 if (sav
->flags
& SADB_X_EXT_OLD
)
165 struct secasvar
*sav
;
174 struct secasvar
*sav
;
176 if (sav
->sah
->saidx
.proto
== IPPROTO_AH
) {
178 "ah_none_mature: protocol and algorithm mismatch.\n"));
185 ah_none_init(state
, sav
)
186 struct ah_algorithm_state
*state
;
187 struct secasvar
*sav
;
193 ah_none_loop(state
, addr
, len
)
194 struct ah_algorithm_state
*state
;
201 ah_none_result(state
, addr
)
202 struct ah_algorithm_state
*state
;
208 ah_keyed_md5_mature(sav
)
209 struct secasvar
*sav
;
211 /* anything is okay */
216 ah_keyed_md5_init(state
, sav
)
217 struct ah_algorithm_state
*state
;
218 struct secasvar
*sav
;
221 panic("ah_keyed_md5_init: what?");
224 state
->foo
= (void *)_MALLOC(sizeof(MD5_CTX
), M_TEMP
, M_WAITOK
);
225 if (state
->foo
== NULL
)
226 panic("ah_keyed_md5_init: what?");
227 MD5Init((MD5_CTX
*)state
->foo
);
229 MD5Update((MD5_CTX
*)state
->foo
,
230 (u_int8_t
*)_KEYBUF(state
->sav
->key_auth
),
231 (u_int
)_KEYLEN(state
->sav
->key_auth
));
236 * We cannot simply use md5_pad() since the function
237 * won't update the total length.
243 if (_KEYLEN(state
->sav
->key_auth
) < 56)
244 padlen
= 64 - 8 - _KEYLEN(state
->sav
->key_auth
);
246 padlen
= 64 + 64 - 8 - _KEYLEN(state
->sav
->key_auth
);
247 keybitlen
= _KEYLEN(state
->sav
->key_auth
);
251 MD5Update((MD5_CTX
*)state
->foo
, &buf
[0], 1);
254 bzero(buf
, sizeof(buf
));
255 while (sizeof(buf
) < padlen
) {
256 MD5Update((MD5_CTX
*)state
->foo
, &buf
[0], sizeof(buf
));
257 padlen
-= sizeof(buf
);
260 MD5Update((MD5_CTX
*)state
->foo
, &buf
[0], padlen
);
263 buf
[0] = (keybitlen
>> 0) & 0xff;
264 buf
[1] = (keybitlen
>> 8) & 0xff;
265 buf
[2] = (keybitlen
>> 16) & 0xff;
266 buf
[3] = (keybitlen
>> 24) & 0xff;
267 MD5Update((MD5_CTX
*)state
->foo
, buf
, 8);
273 ah_keyed_md5_loop(state
, addr
, len
)
274 struct ah_algorithm_state
*state
;
279 panic("ah_keyed_md5_loop: what?");
281 MD5Update((MD5_CTX
*)state
->foo
, addr
, len
);
285 ah_keyed_md5_result(state
, addr
)
286 struct ah_algorithm_state
*state
;
292 panic("ah_keyed_md5_result: what?");
295 MD5Update((MD5_CTX
*)state
->foo
,
296 (u_int8_t
*)_KEYBUF(state
->sav
->key_auth
),
297 (u_int
)_KEYLEN(state
->sav
->key_auth
));
299 MD5Final(&digest
[0], (MD5_CTX
*)state
->foo
);
300 _FREE(state
->foo
, M_TEMP
);
301 bcopy(&digest
[0], (void *)addr
, sizeof(digest
));
305 ah_keyed_sha1_mature(sav
)
306 struct secasvar
*sav
;
308 struct ah_algorithm
*algo
;
310 if (!sav
->key_auth
) {
311 ipseclog((LOG_ERR
, "ah_keyed_sha1_mature: no key is given.\n"));
314 algo
= &ah_algorithms
[sav
->alg_auth
];
315 if (sav
->key_auth
->sadb_key_bits
< algo
->keymin
316 || algo
->keymax
< sav
->key_auth
->sadb_key_bits
) {
318 "ah_keyed_sha1_mature: invalid key length %d.\n",
319 sav
->key_auth
->sadb_key_bits
));
327 ah_keyed_sha1_init(state
, sav
)
328 struct ah_algorithm_state
*state
;
329 struct secasvar
*sav
;
334 panic("ah_keyed_sha1_init: what?");
337 state
->foo
= (void *)_MALLOC(sizeof(SHA1_CTX
), M_TEMP
, M_WAITOK
);
339 panic("ah_keyed_sha1_init: what?");
341 ctxt
= (SHA1_CTX
*)state
->foo
;
345 SHA1Update(ctxt
, (u_int8_t
*)_KEYBUF(state
->sav
->key_auth
),
346 (u_int
)_KEYLEN(state
->sav
->key_auth
));
356 if (_KEYLEN(state
->sav
->key_auth
) < 56)
357 padlen
= 64 - 8 - _KEYLEN(state
->sav
->key_auth
);
359 padlen
= 64 + 64 - 8 - _KEYLEN(state
->sav
->key_auth
);
360 keybitlen
= _KEYLEN(state
->sav
->key_auth
);
364 SHA1Update(ctxt
, &buf
[0], 1);
367 bzero(buf
, sizeof(buf
));
368 while (sizeof(buf
) < padlen
) {
369 SHA1Update(ctxt
, &buf
[0], sizeof(buf
));
370 padlen
-= sizeof(buf
);
373 SHA1Update(ctxt
, &buf
[0], padlen
);
376 buf
[0] = (keybitlen
>> 0) & 0xff;
377 buf
[1] = (keybitlen
>> 8) & 0xff;
378 buf
[2] = (keybitlen
>> 16) & 0xff;
379 buf
[3] = (keybitlen
>> 24) & 0xff;
380 SHA1Update(ctxt
, buf
, 8);
386 ah_keyed_sha1_loop(state
, addr
, len
)
387 struct ah_algorithm_state
*state
;
393 if (!state
|| !state
->foo
)
394 panic("ah_keyed_sha1_loop: what?");
395 ctxt
= (SHA1_CTX
*)state
->foo
;
397 SHA1Update(ctxt
, (caddr_t
)addr
, (size_t)len
);
401 ah_keyed_sha1_result(state
, addr
)
402 struct ah_algorithm_state
*state
;
405 u_char digest
[SHA1_RESULTLEN
]; /* SHA-1 generates 160 bits */
408 if (!state
|| !state
->foo
)
409 panic("ah_keyed_sha1_result: what?");
410 ctxt
= (SHA1_CTX
*)state
->foo
;
413 SHA1Update(ctxt
, (u_int8_t
*)_KEYBUF(state
->sav
->key_auth
),
414 (u_int
)_KEYLEN(state
->sav
->key_auth
));
416 SHA1Final((caddr_t
)&digest
[0], ctxt
);
417 bcopy(&digest
[0], (void *)addr
, HMACSIZE
);
419 _FREE(state
->foo
, M_TEMP
);
423 ah_hmac_md5_mature(sav
)
424 struct secasvar
*sav
;
426 struct ah_algorithm
*algo
;
428 if (!sav
->key_auth
) {
429 ipseclog((LOG_ERR
, "ah_hmac_md5_mature: no key is given.\n"));
432 algo
= &ah_algorithms
[sav
->alg_auth
];
433 if (sav
->key_auth
->sadb_key_bits
< algo
->keymin
434 || algo
->keymax
< sav
->key_auth
->sadb_key_bits
) {
436 "ah_hmac_md5_mature: invalid key length %d.\n",
437 sav
->key_auth
->sadb_key_bits
));
445 ah_hmac_md5_init(state
, sav
)
446 struct ah_algorithm_state
*state
;
447 struct secasvar
*sav
;
458 panic("ah_hmac_md5_init: what?");
461 state
->foo
= (void *)_MALLOC(64 + 64 + sizeof(MD5_CTX
), M_TEMP
, M_WAITOK
);
463 panic("ah_hmac_md5_init: what?");
465 ipad
= (u_char
*)state
->foo
;
466 opad
= (u_char
*)(ipad
+ 64);
467 ctxt
= (MD5_CTX
*)(opad
+ 64);
469 /* compress the key if necessery */
470 if (64 < _KEYLEN(state
->sav
->key_auth
)) {
472 MD5Update(ctxt
, _KEYBUF(state
->sav
->key_auth
),
473 _KEYLEN(state
->sav
->key_auth
));
474 MD5Final(&tk
[0], ctxt
);
478 key
= _KEYBUF(state
->sav
->key_auth
);
479 keylen
= _KEYLEN(state
->sav
->key_auth
);
484 bcopy(key
, ipad
, keylen
);
485 bcopy(key
, opad
, keylen
);
486 for (i
= 0; i
< 64; i
++) {
492 MD5Update(ctxt
, ipad
, 64);
496 ah_hmac_md5_loop(state
, addr
, len
)
497 struct ah_algorithm_state
*state
;
503 if (!state
|| !state
->foo
)
504 panic("ah_hmac_md5_loop: what?");
505 ctxt
= (MD5_CTX
*)(((caddr_t
)state
->foo
) + 128);
506 MD5Update(ctxt
, addr
, len
);
510 ah_hmac_md5_result(state
, addr
)
511 struct ah_algorithm_state
*state
;
519 if (!state
|| !state
->foo
)
520 panic("ah_hmac_md5_result: what?");
522 ipad
= (u_char
*)state
->foo
;
523 opad
= (u_char
*)(ipad
+ 64);
524 ctxt
= (MD5_CTX
*)(opad
+ 64);
526 MD5Final(&digest
[0], ctxt
);
529 MD5Update(ctxt
, opad
, 64);
530 MD5Update(ctxt
, &digest
[0], sizeof(digest
));
531 MD5Final(&digest
[0], ctxt
);
533 bcopy(&digest
[0], (void *)addr
, HMACSIZE
);
535 _FREE(state
->foo
, M_TEMP
);
539 ah_hmac_sha1_mature(sav
)
540 struct secasvar
*sav
;
542 struct ah_algorithm
*algo
;
544 if (!sav
->key_auth
) {
545 ipseclog((LOG_ERR
, "ah_hmac_sha1_mature: no key is given.\n"));
548 algo
= &ah_algorithms
[sav
->alg_auth
];
549 if (sav
->key_auth
->sadb_key_bits
< algo
->keymin
550 || algo
->keymax
< sav
->key_auth
->sadb_key_bits
) {
552 "ah_hmac_sha1_mature: invalid key length %d.\n",
553 sav
->key_auth
->sadb_key_bits
));
561 ah_hmac_sha1_init(state
, sav
)
562 struct ah_algorithm_state
*state
;
563 struct secasvar
*sav
;
568 u_char tk
[SHA1_RESULTLEN
]; /* SHA-1 generates 160 bits */
574 panic("ah_hmac_sha1_init: what?");
577 state
->foo
= (void *)_MALLOC(64 + 64 + sizeof(SHA1_CTX
),
580 panic("ah_hmac_sha1_init: what?");
582 ipad
= (u_char
*)state
->foo
;
583 opad
= (u_char
*)(ipad
+ 64);
584 ctxt
= (SHA1_CTX
*)(opad
+ 64);
586 /* compress the key if necessery */
587 if (64 < _KEYLEN(state
->sav
->key_auth
)) {
589 SHA1Update(ctxt
, _KEYBUF(state
->sav
->key_auth
),
590 _KEYLEN(state
->sav
->key_auth
));
591 SHA1Final(&tk
[0], ctxt
);
593 keylen
= SHA1_RESULTLEN
;
595 key
= _KEYBUF(state
->sav
->key_auth
);
596 keylen
= _KEYLEN(state
->sav
->key_auth
);
601 bcopy(key
, ipad
, keylen
);
602 bcopy(key
, opad
, keylen
);
603 for (i
= 0; i
< 64; i
++) {
609 SHA1Update(ctxt
, ipad
, 64);
613 ah_hmac_sha1_loop(state
, addr
, len
)
614 struct ah_algorithm_state
*state
;
620 if (!state
|| !state
->foo
)
621 panic("ah_hmac_sha1_loop: what?");
623 ctxt
= (SHA1_CTX
*)(((u_char
*)state
->foo
) + 128);
624 SHA1Update(ctxt
, (caddr_t
)addr
, (size_t)len
);
628 ah_hmac_sha1_result(state
, addr
)
629 struct ah_algorithm_state
*state
;
632 u_char digest
[SHA1_RESULTLEN
]; /* SHA-1 generates 160 bits */
637 if (!state
|| !state
->foo
)
638 panic("ah_hmac_sha1_result: what?");
640 ipad
= (u_char
*)state
->foo
;
641 opad
= (u_char
*)(ipad
+ 64);
642 ctxt
= (SHA1_CTX
*)(opad
+ 64);
644 SHA1Final((caddr_t
)&digest
[0], ctxt
);
647 SHA1Update(ctxt
, opad
, 64);
648 SHA1Update(ctxt
, (caddr_t
)&digest
[0], sizeof(digest
));
649 SHA1Final((caddr_t
)&digest
[0], ctxt
);
651 bcopy(&digest
[0], (void *)addr
, HMACSIZE
);
653 _FREE(state
->foo
, M_TEMP
);
656 /*------------------------------------------------------------*/
659 * go generate the checksum.
662 ah_update_mbuf(m
, off
, len
, algo
, algos
)
666 struct ah_algorithm
*algo
;
667 struct ah_algorithm_state
*algos
;
672 /* easy case first */
673 if (off
+ len
<= m
->m_len
) {
674 (algo
->update
)(algos
, mtod(m
, caddr_t
) + off
, len
);
678 for (n
= m
; n
; n
= n
->m_next
) {
686 panic("ah_update_mbuf: wrong offset specified");
688 for (/*nothing*/; n
&& len
> 0; n
= n
->m_next
) {
691 if (n
->m_len
- off
< len
)
692 tlen
= n
->m_len
- off
;
696 (algo
->update
)(algos
, mtod(n
, caddr_t
) + off
, tlen
);
704 * Go generate the checksum. This function won't modify the mbuf chain
707 * NOTE: the function does not free mbuf on failure.
708 * Don't use m_copy(), it will try to share cluster mbuf by using refcnt.
711 ah4_calccksum(m
, ahdat
, algo
, sav
)
714 struct ah_algorithm
*algo
;
715 struct secasvar
*sav
;
720 struct ah_algorithm_state algos
;
721 u_char sumbuf
[AH_MAXSUMSIZE
];
724 struct mbuf
*n
= NULL
;
726 if ((m
->m_flags
& M_PKTHDR
) == 0)
730 hdrtype
= -1; /*dummy, it is called IPPROTO_IP*/
734 (algo
->init
)(&algos
, sav
);
736 advancewidth
= 0; /*safety*/
741 case -1: /*first one only*/
744 * copy ip hdr, modify to fit the AH checksum rule,
745 * then take a checksum.
750 m_copydata(m
, off
, sizeof(iphdr
), (caddr_t
)&iphdr
);
752 hlen
= IP_VHL_HL(iphdr
.ip_vhl
) << 2;
754 hlen
= iphdr
.ip_hl
<< 2;
757 iphdr
.ip_sum
= htons(0);
760 iphdr
.ip_off
= htons(ntohs(iphdr
.ip_off
) & ip4_ah_offsetmask
);
761 (algo
->update
)(&algos
, (caddr_t
)&iphdr
, sizeof(struct ip
));
763 if (hlen
!= sizeof(struct ip
)) {
767 if (hlen
> MCLBYTES
) {
771 MGET(n
, M_DONTWAIT
, MT_DATA
);
772 if (n
&& hlen
> MLEN
) {
773 MCLGET(n
, M_DONTWAIT
);
774 if ((n
->m_flags
& M_EXT
) == 0) {
783 m_copydata(m
, off
, hlen
, mtod(n
, caddr_t
));
786 * IP options processing.
787 * See RFC2402 appendix A.
789 p
= mtod(n
, u_char
*);
790 i
= sizeof(struct ip
);
793 switch (p
[i
+ IPOPT_OPTVAL
]) {
799 case IPOPT_SECURITY
: /* 0x82 */
800 case 0x85: /* Extended security */
801 case 0x86: /* Commercial security */
802 case 0x94: /* Router alert */
803 case 0x95: /* RFC1770 */
804 l
= p
[i
+ IPOPT_OLEN
];
808 l
= p
[i
+ IPOPT_OLEN
];
812 if (l
<= 0 || hlen
- i
< l
) {
814 "ah4_calccksum: invalid IP option "
815 "(type=%02x len=%02x)\n",
825 if (p
[i
+ IPOPT_OPTVAL
] == IPOPT_EOL
)
829 p
= mtod(n
, u_char
*) + sizeof(struct ip
);
830 (algo
->update
)(&algos
, p
, hlen
- sizeof(struct ip
));
836 hdrtype
= (iphdr
.ip_p
) & 0xff;
848 m_copydata(m
, off
, sizeof(ah
), (caddr_t
)&ah
);
849 hdrsiz
= (sav
->flags
& SADB_X_EXT_OLD
)
851 : sizeof(struct newah
);
852 siz
= (*algo
->sumsiz
)(sav
);
853 totlen
= (ah
.ah_len
+ 2) << 2;
856 * special treatment is necessary for the first one, not others
859 if (totlen
> m
->m_pkthdr
.len
- off
||
864 MGET(n
, M_DONTWAIT
, MT_DATA
);
865 if (n
&& totlen
> MLEN
) {
866 MCLGET(n
, M_DONTWAIT
);
867 if ((n
->m_flags
& M_EXT
) == 0) {
876 m_copydata(m
, off
, totlen
, mtod(n
, caddr_t
));
878 bzero(mtod(n
, caddr_t
) + hdrsiz
, siz
);
879 (algo
->update
)(&algos
, mtod(n
, caddr_t
), n
->m_len
);
883 ah_update_mbuf(m
, off
, totlen
, algo
, &algos
);
887 advancewidth
= totlen
;
892 ah_update_mbuf(m
, off
, m
->m_pkthdr
.len
- off
, algo
, &algos
);
893 advancewidth
= m
->m_pkthdr
.len
- off
;
898 if (off
< m
->m_pkthdr
.len
)
901 (algo
->result
)(&algos
, &sumbuf
[0]);
902 bcopy(&sumbuf
[0], ahdat
, (*algo
->sumsiz
)(sav
));
916 * Go generate the checksum. This function won't modify the mbuf chain
919 * NOTE: the function does not free mbuf on failure.
920 * Don't use m_copy(), it will try to share cluster mbuf by using refcnt.
923 ah6_calccksum(m
, ahdat
, algo
, sav
)
926 struct ah_algorithm
*algo
;
927 struct secasvar
*sav
;
931 struct mbuf
*n
= NULL
;
934 struct ah_algorithm_state algos
;
935 u_char sumbuf
[AH_MAXSUMSIZE
];
937 if ((m
->m_flags
& M_PKTHDR
) == 0)
940 (algo
->init
)(&algos
, sav
);
943 proto
= IPPROTO_IPV6
;
948 newoff
= ip6_nexthdr(m
, off
, proto
, &nxt
);
950 newoff
= m
->m_pkthdr
.len
;
951 else if (newoff
<= off
) {
959 * special treatment is necessary for the first one, not others
962 struct ip6_hdr ip6copy
;
964 if (newoff
- off
!= sizeof(struct ip6_hdr
)) {
969 m_copydata(m
, off
, newoff
- off
, (caddr_t
)&ip6copy
);
971 ip6copy
.ip6_flow
= 0;
972 ip6copy
.ip6_vfc
&= ~IPV6_VERSION_MASK
;
973 ip6copy
.ip6_vfc
|= IPV6_VERSION
;
974 ip6copy
.ip6_hlim
= 0;
975 if (IN6_IS_ADDR_LINKLOCAL(&ip6copy
.ip6_src
))
976 ip6copy
.ip6_src
.s6_addr16
[1] = 0x0000;
977 if (IN6_IS_ADDR_LINKLOCAL(&ip6copy
.ip6_dst
))
978 ip6copy
.ip6_dst
.s6_addr16
[1] = 0x0000;
979 (algo
->update
)(&algos
, (caddr_t
)&ip6copy
,
980 sizeof(struct ip6_hdr
));
982 newoff
= m
->m_pkthdr
.len
;
983 ah_update_mbuf(m
, off
, m
->m_pkthdr
.len
- off
, algo
,
993 hdrsiz
= (sav
->flags
& SADB_X_EXT_OLD
)
995 : sizeof(struct newah
);
996 siz
= (*algo
->sumsiz
)(sav
);
999 * special treatment is necessary for the first one, not others
1002 if (newoff
- off
> MCLBYTES
) {
1006 MGET(n
, M_DONTWAIT
, MT_DATA
);
1007 if (n
&& newoff
- off
> MLEN
) {
1008 MCLGET(n
, M_DONTWAIT
);
1009 if ((n
->m_flags
& M_EXT
) == 0) {
1018 m_copydata(m
, off
, newoff
- off
, mtod(n
, caddr_t
));
1019 n
->m_len
= newoff
- off
;
1020 bzero(mtod(n
, caddr_t
) + hdrsiz
, siz
);
1021 (algo
->update
)(&algos
, mtod(n
, caddr_t
), n
->m_len
);
1025 ah_update_mbuf(m
, off
, newoff
- off
, algo
, &algos
);
1030 case IPPROTO_HOPOPTS
:
1031 case IPPROTO_DSTOPTS
:
1033 struct ip6_ext
*ip6e
;
1035 u_int8_t
*p
, *optend
, *optp
;
1037 if (newoff
- off
> MCLBYTES
) {
1041 MGET(n
, M_DONTWAIT
, MT_DATA
);
1042 if (n
&& newoff
- off
> MLEN
) {
1043 MCLGET(n
, M_DONTWAIT
);
1044 if ((n
->m_flags
& M_EXT
) == 0) {
1053 m_copydata(m
, off
, newoff
- off
, mtod(n
, caddr_t
));
1054 n
->m_len
= newoff
- off
;
1056 ip6e
= mtod(n
, struct ip6_ext
*);
1057 hdrlen
= (ip6e
->ip6e_len
+ 1) << 3;
1058 if (newoff
- off
< hdrlen
) {
1064 p
= mtod(n
, u_int8_t
*);
1065 optend
= p
+ hdrlen
;
1068 * ICV calculation for the options header including all
1069 * options. This part is a little tricky since there are
1070 * two type of options; mutable and immutable. We try to
1071 * null-out mutable ones here.
1074 while (optp
< optend
) {
1075 if (optp
[0] == IP6OPT_PAD1
)
1078 if (optp
+ 2 > optend
) {
1084 optlen
= optp
[1] + 2;
1086 if (optp
[0] & IP6OPT_MUTABLE
)
1087 bzero(optp
+ 2, optlen
- 2);
1093 (algo
->update
)(&algos
, mtod(n
, caddr_t
), n
->m_len
);
1099 case IPPROTO_ROUTING
:
1101 * For an input packet, we can just calculate `as is'.
1102 * For an output packet, we assume ip6_output have already
1103 * made packet how it will be received at the final
1109 ah_update_mbuf(m
, off
, newoff
- off
, algo
, &algos
);
1113 if (newoff
< m
->m_pkthdr
.len
) {
1119 (algo
->result
)(&algos
, &sumbuf
[0]);
1120 bcopy(&sumbuf
[0], ahdat
, (*algo
->sumsiz
)(sav
));