2 * Copyright (c) 2008 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 /* $FreeBSD: src/sys/netinet6/ah_core.c,v 1.2.2.4 2001/07/03 11:01:49 ume Exp $ */
30 /* $KAME: ah_core.c,v 1.44 2001/03/12 11:24:39 itojun Exp $ */
33 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
34 * All rights reserved.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the project nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
48 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * RFC1826/2402 authentication header.
65 /* TODO: have shared routines for hmac-* algorithms */
67 #include <sys/param.h>
68 #include <sys/systm.h>
69 #include <sys/malloc.h>
71 #include <sys/domain.h>
72 #include <sys/protosw.h>
73 #include <sys/socket.h>
74 #include <sys/socketvar.h>
75 #include <sys/errno.h>
77 #include <sys/syslog.h>
80 #include <net/route.h>
82 #include <netinet/in.h>
83 #include <netinet/in_systm.h>
84 #include <netinet/ip.h>
85 #include <netinet/in_var.h>
88 #include <netinet/ip6.h>
89 #include <netinet6/ip6_var.h>
90 #include <netinet/icmp6.h>
93 #include <netinet6/ipsec.h>
95 #include <netinet6/ipsec6.h>
97 #include <netinet6/ah.h>
99 #include <netinet6/ah6.h>
102 #include <netinet6/esp.h>
104 #include <netinet6/esp6.h>
107 #include <net/pfkeyv2.h>
108 #include <netkey/keydb.h>
109 #include <libkern/crypto/md5.h>
110 #include <libkern/crypto/sha1.h>
111 #include <crypto/sha2/sha2.h>
113 #include <net/net_osdep.h>
117 static int ah_sumsiz_1216(struct secasvar
*);
118 static int ah_sumsiz_zero(struct secasvar
*);
119 static int ah_none_mature(struct secasvar
*);
120 static int ah_none_init(struct ah_algorithm_state
*, struct secasvar
*);
121 static void ah_none_loop(struct ah_algorithm_state
*, caddr_t
, size_t);
122 static void ah_none_result(struct ah_algorithm_state
*, caddr_t
);
123 static int ah_keyed_md5_mature(struct secasvar
*);
124 static int ah_keyed_md5_init(struct ah_algorithm_state
*, struct secasvar
*);
125 static void ah_keyed_md5_loop(struct ah_algorithm_state
*, caddr_t
, size_t);
126 static void ah_keyed_md5_result(struct ah_algorithm_state
*, caddr_t
);
127 static int ah_keyed_sha1_mature(struct secasvar
*);
128 static int ah_keyed_sha1_init(struct ah_algorithm_state
*, struct secasvar
*);
129 static void ah_keyed_sha1_loop(struct ah_algorithm_state
*, caddr_t
, size_t);
130 static void ah_keyed_sha1_result(struct ah_algorithm_state
*, caddr_t
);
131 static int ah_hmac_md5_mature(struct secasvar
*);
132 static int ah_hmac_md5_init(struct ah_algorithm_state
*, struct secasvar
*);
133 static void ah_hmac_md5_loop(struct ah_algorithm_state
*, caddr_t
, size_t);
134 static void ah_hmac_md5_result(struct ah_algorithm_state
*, caddr_t
);
135 static int ah_hmac_sha1_mature(struct secasvar
*);
136 static int ah_hmac_sha1_init(struct ah_algorithm_state
*, struct secasvar
*);
137 static void ah_hmac_sha1_loop(struct ah_algorithm_state
*, caddr_t
, size_t);
138 static void ah_hmac_sha1_result(struct ah_algorithm_state
*, caddr_t
);
140 static int ah_sumsiz_sha2_256(struct secasvar
*);
141 static int ah_hmac_sha2_256_mature(struct secasvar
*);
142 static int ah_hmac_sha2_256_init(struct ah_algorithm_state
*,
144 static void ah_hmac_sha2_256_loop(struct ah_algorithm_state
*, caddr_t
, size_t);
145 static void ah_hmac_sha2_256_result(struct ah_algorithm_state
*, caddr_t
);
146 static int ah_sumsiz_sha2_384(struct secasvar
*);
147 static int ah_hmac_sha2_384_mature(struct secasvar
*);
148 static int ah_hmac_sha2_384_init(struct ah_algorithm_state
*,
150 static void ah_hmac_sha2_384_loop(struct ah_algorithm_state
*, caddr_t
, size_t);
151 static void ah_hmac_sha2_384_result(struct ah_algorithm_state
*, caddr_t
);
152 static int ah_sumsiz_sha2_512(struct secasvar
*);
153 static int ah_hmac_sha2_512_mature(struct secasvar
*);
154 static int ah_hmac_sha2_512_init(struct ah_algorithm_state
*,
156 static void ah_hmac_sha2_512_loop(struct ah_algorithm_state
*, caddr_t
, size_t);
157 static void ah_hmac_sha2_512_result(struct ah_algorithm_state
*, caddr_t
);
158 #endif /* ALLCRYPTO */
160 static void ah_update_mbuf(struct mbuf
*, int, int,
161 const struct ah_algorithm
*, struct ah_algorithm_state
*);
163 const struct ah_algorithm
*
164 ah_algorithm_lookup(idx
)
167 /* checksum algorithms */
168 static struct ah_algorithm hmac_md5
=
169 { ah_sumsiz_1216
, ah_hmac_md5_mature
, 128, 128, "hmac-md5",
170 ah_hmac_md5_init
, ah_hmac_md5_loop
,
171 ah_hmac_md5_result
, };
172 static struct ah_algorithm keyed_md5
=
173 { ah_sumsiz_1216
, ah_keyed_md5_mature
, 128, 128, "keyed-md5",
174 ah_keyed_md5_init
, ah_keyed_md5_loop
,
175 ah_keyed_md5_result
, };
176 static struct ah_algorithm hmac_sha1
=
177 { ah_sumsiz_1216
, ah_hmac_sha1_mature
, 160, 160, "hmac-sha1",
178 ah_hmac_sha1_init
, ah_hmac_sha1_loop
,
179 ah_hmac_sha1_result
, };
180 static struct ah_algorithm keyed_sha1
=
181 { ah_sumsiz_1216
, ah_keyed_sha1_mature
, 160, 160, "keyed-sha1",
182 ah_keyed_sha1_init
, ah_keyed_sha1_loop
,
183 ah_keyed_sha1_result
, };
184 static struct ah_algorithm ah_none
=
185 { ah_sumsiz_zero
, ah_none_mature
, 0, 2048, "none",
186 ah_none_init
, ah_none_loop
, ah_none_result
, };
188 static struct ah_algorithm hmac_sha2_256
=
189 { ah_sumsiz_sha2_256
, ah_hmac_sha2_256_mature
, 256, 256,
191 ah_hmac_sha2_256_init
, ah_hmac_sha2_256_loop
,
192 ah_hmac_sha2_256_result
, };
193 static struct ah_algorithm hmac_sha2_384
=
194 { ah_sumsiz_sha2_384
, ah_hmac_sha2_384_mature
, 384, 384,
196 ah_hmac_sha2_384_init
, ah_hmac_sha2_384_loop
,
197 ah_hmac_sha2_384_result
, };
198 static struct ah_algorithm hmac_sha2_512
=
199 { ah_sumsiz_sha2_512
, ah_hmac_sha2_512_mature
, 512, 512,
201 ah_hmac_sha2_512_init
, ah_hmac_sha2_512_loop
,
202 ah_hmac_sha2_512_result
, };
203 #endif /* ALLCRYPTO */
206 case SADB_AALG_MD5HMAC
:
208 case SADB_AALG_SHA1HMAC
:
210 case SADB_X_AALG_MD5
:
212 case SADB_X_AALG_SHA
:
214 case SADB_X_AALG_NULL
:
217 case SADB_X_AALG_SHA2_256
:
218 return &hmac_sha2_256
;
219 case SADB_X_AALG_SHA2_384
:
220 return &hmac_sha2_384
;
221 case SADB_X_AALG_SHA2_512
:
222 return &hmac_sha2_512
;
223 #endif /* ALLCRYPTO */
232 struct secasvar
*sav
;
236 if (sav
->flags
& SADB_X_EXT_OLD
)
244 struct secasvar
*sav
;
253 struct secasvar
*sav
;
255 if (sav
->sah
->saidx
.proto
== IPPROTO_AH
) {
257 "ah_none_mature: protocol and algorithm mismatch.\n"));
265 struct ah_algorithm_state
*state
,
266 __unused
struct secasvar
*sav
)
274 __unused
struct ah_algorithm_state
*state
,
275 __unused caddr_t addr
,
282 __unused
struct ah_algorithm_state
*state
,
283 __unused caddr_t addr
)
289 __unused
struct secasvar
*sav
)
291 /* anything is okay */
296 ah_keyed_md5_init(state
, sav
)
297 struct ah_algorithm_state
*state
;
298 struct secasvar
*sav
;
305 panic("ah_keyed_md5_init: what?");
308 state
->foo
= (void *)_MALLOC(sizeof(MD5_CTX
), M_TEMP
, M_NOWAIT
);
309 if (state
->foo
== NULL
)
312 MD5Init((MD5_CTX
*)state
->foo
);
314 MD5Update((MD5_CTX
*)state
->foo
,
315 (u_int8_t
*)_KEYBUF(state
->sav
->key_auth
),
316 (u_int
)_KEYLEN(state
->sav
->key_auth
));
320 * We cannot simply use md5_pad() since the function
321 * won't update the total length.
323 if (_KEYLEN(state
->sav
->key_auth
) < 56)
324 padlen
= 64 - 8 - _KEYLEN(state
->sav
->key_auth
);
326 padlen
= 64 + 64 - 8 - _KEYLEN(state
->sav
->key_auth
);
327 keybitlen
= _KEYLEN(state
->sav
->key_auth
);
331 MD5Update((MD5_CTX
*)state
->foo
, &buf
[0], 1);
334 bzero(buf
, sizeof(buf
));
335 while (sizeof(buf
) < padlen
) {
336 MD5Update((MD5_CTX
*)state
->foo
, &buf
[0], sizeof(buf
));
337 padlen
-= sizeof(buf
);
340 MD5Update((MD5_CTX
*)state
->foo
, &buf
[0], padlen
);
343 buf
[0] = (keybitlen
>> 0) & 0xff;
344 buf
[1] = (keybitlen
>> 8) & 0xff;
345 buf
[2] = (keybitlen
>> 16) & 0xff;
346 buf
[3] = (keybitlen
>> 24) & 0xff;
347 MD5Update((MD5_CTX
*)state
->foo
, buf
, 8);
354 ah_keyed_md5_loop(state
, addr
, len
)
355 struct ah_algorithm_state
*state
;
360 panic("ah_keyed_md5_loop: what?");
362 MD5Update((MD5_CTX
*)state
->foo
, addr
, len
);
366 ah_keyed_md5_result(state
, addr
)
367 struct ah_algorithm_state
*state
;
373 panic("ah_keyed_md5_result: what?");
376 MD5Update((MD5_CTX
*)state
->foo
,
377 (u_int8_t
*)_KEYBUF(state
->sav
->key_auth
),
378 (u_int
)_KEYLEN(state
->sav
->key_auth
));
380 MD5Final(&digest
[0], (MD5_CTX
*)state
->foo
);
381 FREE(state
->foo
, M_TEMP
);
382 bcopy(&digest
[0], (void *)addr
, sizeof(digest
));
386 ah_keyed_sha1_mature(sav
)
387 struct secasvar
*sav
;
389 const struct ah_algorithm
*algo
;
391 if (!sav
->key_auth
) {
392 ipseclog((LOG_ERR
, "ah_keyed_sha1_mature: no key is given.\n"));
396 algo
= ah_algorithm_lookup(sav
->alg_auth
);
398 ipseclog((LOG_ERR
, "ah_keyed_sha1_mature: unsupported algorithm.\n"));
402 if (sav
->key_auth
->sadb_key_bits
< algo
->keymin
403 || algo
->keymax
< sav
->key_auth
->sadb_key_bits
) {
405 "ah_keyed_sha1_mature: invalid key length %d.\n",
406 sav
->key_auth
->sadb_key_bits
));
414 ah_keyed_sha1_init(state
, sav
)
415 struct ah_algorithm_state
*state
;
416 struct secasvar
*sav
;
424 panic("ah_keyed_sha1_init: what?");
427 state
->foo
= (void *)_MALLOC(sizeof(SHA1_CTX
), M_TEMP
, M_NOWAIT
);
431 ctxt
= (SHA1_CTX
*)state
->foo
;
435 SHA1Update(ctxt
, (u_int8_t
*)_KEYBUF(state
->sav
->key_auth
),
436 (u_int
)_KEYLEN(state
->sav
->key_auth
));
441 if (_KEYLEN(state
->sav
->key_auth
) < 56)
442 padlen
= 64 - 8 - _KEYLEN(state
->sav
->key_auth
);
444 padlen
= 64 + 64 - 8 - _KEYLEN(state
->sav
->key_auth
);
445 keybitlen
= _KEYLEN(state
->sav
->key_auth
);
449 SHA1Update(ctxt
, &buf
[0], 1);
452 bzero(buf
, sizeof(buf
));
453 while (sizeof(buf
) < padlen
) {
454 SHA1Update(ctxt
, &buf
[0], sizeof(buf
));
455 padlen
-= sizeof(buf
);
458 SHA1Update(ctxt
, &buf
[0], padlen
);
461 buf
[0] = (keybitlen
>> 0) & 0xff;
462 buf
[1] = (keybitlen
>> 8) & 0xff;
463 buf
[2] = (keybitlen
>> 16) & 0xff;
464 buf
[3] = (keybitlen
>> 24) & 0xff;
465 SHA1Update(ctxt
, buf
, 8);
472 ah_keyed_sha1_loop(state
, addr
, len
)
473 struct ah_algorithm_state
*state
;
479 if (!state
|| !state
->foo
)
480 panic("ah_keyed_sha1_loop: what?");
481 ctxt
= (SHA1_CTX
*)state
->foo
;
483 SHA1Update(ctxt
, (caddr_t
)addr
, (size_t)len
);
487 ah_keyed_sha1_result(state
, addr
)
488 struct ah_algorithm_state
*state
;
491 u_char digest
[SHA1_RESULTLEN
]; /* SHA-1 generates 160 bits */
494 if (!state
|| !state
->foo
)
495 panic("ah_keyed_sha1_result: what?");
496 ctxt
= (SHA1_CTX
*)state
->foo
;
499 SHA1Update(ctxt
, (u_int8_t
*)_KEYBUF(state
->sav
->key_auth
),
500 (u_int
)_KEYLEN(state
->sav
->key_auth
));
502 SHA1Final((caddr_t
)&digest
[0], ctxt
);
503 bcopy(&digest
[0], (void *)addr
, HMACSIZE
);
505 FREE(state
->foo
, M_TEMP
);
509 ah_hmac_md5_mature(sav
)
510 struct secasvar
*sav
;
512 const struct ah_algorithm
*algo
;
514 if (!sav
->key_auth
) {
515 ipseclog((LOG_ERR
, "ah_hmac_md5_mature: no key is given.\n"));
519 algo
= ah_algorithm_lookup(sav
->alg_auth
);
521 ipseclog((LOG_ERR
, "ah_hmac_md5_mature: unsupported algorithm.\n"));
525 if (sav
->key_auth
->sadb_key_bits
< algo
->keymin
526 || algo
->keymax
< sav
->key_auth
->sadb_key_bits
) {
528 "ah_hmac_md5_mature: invalid key length %d.\n",
529 sav
->key_auth
->sadb_key_bits
));
537 ah_hmac_md5_init(state
, sav
)
538 struct ah_algorithm_state
*state
;
539 struct secasvar
*sav
;
550 panic("ah_hmac_md5_init: what?");
553 state
->foo
= (void *)_MALLOC(64 + 64 + sizeof(MD5_CTX
), M_TEMP
, M_NOWAIT
);
557 ipad
= (u_char
*)state
->foo
;
558 opad
= (u_char
*)(ipad
+ 64);
559 ctxt
= (MD5_CTX
*)(opad
+ 64);
561 /* compress the key if necessery */
562 if (64 < _KEYLEN(state
->sav
->key_auth
)) {
564 MD5Update(ctxt
, _KEYBUF(state
->sav
->key_auth
),
565 _KEYLEN(state
->sav
->key_auth
));
566 MD5Final(&tk
[0], ctxt
);
570 key
= (u_char
*) _KEYBUF(state
->sav
->key_auth
);
571 keylen
= _KEYLEN(state
->sav
->key_auth
);
576 bcopy(key
, ipad
, keylen
);
577 bcopy(key
, opad
, keylen
);
578 for (i
= 0; i
< 64; i
++) {
584 MD5Update(ctxt
, ipad
, 64);
590 ah_hmac_md5_loop(state
, addr
, len
)
591 struct ah_algorithm_state
*state
;
597 if (!state
|| !state
->foo
)
598 panic("ah_hmac_md5_loop: what?");
599 ctxt
= (MD5_CTX
*)(((caddr_t
)state
->foo
) + 128);
600 MD5Update(ctxt
, addr
, len
);
604 ah_hmac_md5_result(state
, addr
)
605 struct ah_algorithm_state
*state
;
613 if (!state
|| !state
->foo
)
614 panic("ah_hmac_md5_result: what?");
616 ipad
= (u_char
*)state
->foo
;
617 opad
= (u_char
*)(ipad
+ 64);
618 ctxt
= (MD5_CTX
*)(opad
+ 64);
620 MD5Final(&digest
[0], ctxt
);
623 MD5Update(ctxt
, opad
, 64);
624 MD5Update(ctxt
, &digest
[0], sizeof(digest
));
625 MD5Final(&digest
[0], ctxt
);
627 bcopy(&digest
[0], (void *)addr
, HMACSIZE
);
629 FREE(state
->foo
, M_TEMP
);
633 ah_hmac_sha1_mature(sav
)
634 struct secasvar
*sav
;
636 const struct ah_algorithm
*algo
;
638 if (!sav
->key_auth
) {
639 ipseclog((LOG_ERR
, "ah_hmac_sha1_mature: no key is given.\n"));
643 algo
= ah_algorithm_lookup(sav
->alg_auth
);
645 ipseclog((LOG_ERR
, "ah_hmac_sha1_mature: unsupported algorithm.\n"));
649 if (sav
->key_auth
->sadb_key_bits
< algo
->keymin
650 || algo
->keymax
< sav
->key_auth
->sadb_key_bits
) {
652 "ah_hmac_sha1_mature: invalid key length %d.\n",
653 sav
->key_auth
->sadb_key_bits
));
661 ah_hmac_sha1_init(state
, sav
)
662 struct ah_algorithm_state
*state
;
663 struct secasvar
*sav
;
668 u_char tk
[SHA1_RESULTLEN
]; /* SHA-1 generates 160 bits */
674 panic("ah_hmac_sha1_init: what?");
677 state
->foo
= (void *)_MALLOC(64 + 64 + sizeof(SHA1_CTX
),
682 ipad
= (u_char
*)state
->foo
;
683 opad
= (u_char
*)(ipad
+ 64);
684 ctxt
= (SHA1_CTX
*)(opad
+ 64);
686 /* compress the key if necessery */
687 if (64 < _KEYLEN(state
->sav
->key_auth
)) {
689 SHA1Update(ctxt
, _KEYBUF(state
->sav
->key_auth
),
690 _KEYLEN(state
->sav
->key_auth
));
691 SHA1Final(&tk
[0], ctxt
);
693 keylen
= SHA1_RESULTLEN
;
695 key
= (u_char
*) _KEYBUF(state
->sav
->key_auth
);
696 keylen
= _KEYLEN(state
->sav
->key_auth
);
701 bcopy(key
, ipad
, keylen
);
702 bcopy(key
, opad
, keylen
);
703 for (i
= 0; i
< 64; i
++) {
709 SHA1Update(ctxt
, ipad
, 64);
715 ah_hmac_sha1_loop(state
, addr
, len
)
716 struct ah_algorithm_state
*state
;
722 if (!state
|| !state
->foo
)
723 panic("ah_hmac_sha1_loop: what?");
725 ctxt
= (SHA1_CTX
*)(((u_char
*)state
->foo
) + 128);
726 SHA1Update(ctxt
, (caddr_t
)addr
, (size_t)len
);
730 ah_hmac_sha1_result(state
, addr
)
731 struct ah_algorithm_state
*state
;
734 u_char digest
[SHA1_RESULTLEN
]; /* SHA-1 generates 160 bits */
739 if (!state
|| !state
->foo
)
740 panic("ah_hmac_sha1_result: what?");
742 ipad
= (u_char
*)state
->foo
;
743 opad
= (u_char
*)(ipad
+ 64);
744 ctxt
= (SHA1_CTX
*)(opad
+ 64);
746 SHA1Final((caddr_t
)&digest
[0], ctxt
);
749 SHA1Update(ctxt
, opad
, 64);
750 SHA1Update(ctxt
, (caddr_t
)&digest
[0], sizeof(digest
));
751 SHA1Final((caddr_t
)&digest
[0], ctxt
);
753 bcopy(&digest
[0], (void *)addr
, HMACSIZE
);
755 FREE(state
->foo
, M_TEMP
);
760 ah_sumsiz_sha2_256(sav
)
761 struct secasvar
*sav
;
765 // return half the output size (in bytes), as per rfc 4868
766 return 16; // 256/(8*2)
770 ah_hmac_sha2_256_mature(sav
)
771 struct secasvar
*sav
;
773 const struct ah_algorithm
*algo
;
775 if (!sav
->key_auth
) {
777 "ah_hmac_sha2_256_mature: no key is given.\n"));
781 algo
= ah_algorithm_lookup(sav
->alg_auth
);
784 "ah_hmac_sha2_256_mature: unsupported algorithm.\n"));
788 if (sav
->key_auth
->sadb_key_bits
< algo
->keymin
||
789 algo
->keymax
< sav
->key_auth
->sadb_key_bits
) {
791 "ah_hmac_sha2_256_mature: invalid key length %d.\n",
792 sav
->key_auth
->sadb_key_bits
));
800 ah_hmac_sha2_256_init(state
, sav
)
801 struct ah_algorithm_state
*state
;
802 struct secasvar
*sav
;
807 u_char tk
[SHA256_DIGEST_LENGTH
];
813 panic("ah_hmac_sha2_256_init: what?");
816 state
->foo
= (void *)_MALLOC(64 + 64 + sizeof(SHA256_CTX
),
821 ipad
= (u_char
*)state
->foo
;
822 opad
= (u_char
*)(ipad
+ 64);
823 ctxt
= (SHA256_CTX
*)(opad
+ 64);
825 /* compress the key if necessery */
826 if (64 < _KEYLEN(state
->sav
->key_auth
)) {
827 bzero(tk
, sizeof(tk
));
828 bzero(ctxt
, sizeof(*ctxt
));
830 SHA256_Update(ctxt
, (const u_int8_t
*) _KEYBUF(state
->sav
->key_auth
),
831 _KEYLEN(state
->sav
->key_auth
));
832 SHA256_Final(&tk
[0], ctxt
);
834 keylen
= sizeof(tk
) < 64 ? sizeof(tk
) : 64;
836 key
= (u_char
*) _KEYBUF(state
->sav
->key_auth
);
837 keylen
= _KEYLEN(state
->sav
->key_auth
);
842 bcopy(key
, ipad
, keylen
);
843 bcopy(key
, opad
, keylen
);
844 for (i
= 0; i
< 64; i
++) {
849 bzero(ctxt
, sizeof(*ctxt
));
851 SHA256_Update(ctxt
, ipad
, 64);
857 ah_hmac_sha2_256_loop(state
, addr
, len
)
858 struct ah_algorithm_state
*state
;
864 if (!state
|| !state
->foo
)
865 panic("ah_hmac_sha2_256_loop: what?");
867 ctxt
= (SHA256_CTX
*)(((u_char
*)state
->foo
) + 128);
868 SHA256_Update(ctxt
, (const u_int8_t
*)addr
, (size_t)len
);
872 ah_hmac_sha2_256_result(state
, addr
)
873 struct ah_algorithm_state
*state
;
880 if (!state
|| !state
->foo
)
881 panic("ah_hmac_sha2_256_result: what?");
883 ipad
= (u_char
*)state
->foo
;
884 opad
= (u_char
*)(ipad
+ 64);
885 ctxt
= (SHA256_CTX
*)(opad
+ 64);
887 SHA256_Final((u_int8_t
*)addr
, ctxt
);
889 bzero(ctxt
, sizeof(*ctxt
));
891 SHA256_Update(ctxt
, opad
, 64);
892 SHA256_Update(ctxt
, (const u_int8_t
*)addr
, SHA256_DIGEST_LENGTH
);
893 SHA256_Final((u_int8_t
*)addr
, ctxt
);
895 FREE(state
->foo
, M_TEMP
);
899 ah_sumsiz_sha2_384(sav
)
900 struct secasvar
*sav
;
904 // return half the output size (in bytes), as per rfc 4868
905 return 24; // 384/(8*2)
909 ah_hmac_sha2_384_mature(sav
)
910 struct secasvar
*sav
;
912 const struct ah_algorithm
*algo
;
914 if (!sav
->key_auth
) {
916 "ah_hmac_sha2_384_mature: no key is given.\n"));
920 algo
= ah_algorithm_lookup(sav
->alg_auth
);
923 "ah_hmac_sha2_384_mature: unsupported algorithm.\n"));
927 if (sav
->key_auth
->sadb_key_bits
< algo
->keymin
||
928 algo
->keymax
< sav
->key_auth
->sadb_key_bits
) {
930 "ah_hmac_sha2_384_mature: invalid key length %d.\n",
931 sav
->key_auth
->sadb_key_bits
));
939 ah_hmac_sha2_384_init(state
, sav
)
940 struct ah_algorithm_state
*state
;
941 struct secasvar
*sav
;
946 u_char tk
[SHA384_DIGEST_LENGTH
];
952 panic("ah_hmac_sha2_384_init: what?");
955 state
->foo
= (void *)_MALLOC(128 + 128 + sizeof(SHA384_CTX
),
959 bzero(state
->foo
, 128 + 128 + sizeof(SHA384_CTX
));
961 ipad
= (u_char
*)state
->foo
;
962 opad
= (u_char
*)(ipad
+ 128);
963 ctxt
= (SHA384_CTX
*)(opad
+ 128);
965 /* compress the key if necessery */
966 if (128 < _KEYLEN(state
->sav
->key_auth
)) {
967 bzero(tk
, sizeof(tk
));
968 bzero(ctxt
, sizeof(*ctxt
));
970 SHA384_Update(ctxt
, (const u_int8_t
*) _KEYBUF(state
->sav
->key_auth
),
971 _KEYLEN(state
->sav
->key_auth
));
972 SHA384_Final(&tk
[0], ctxt
);
974 keylen
= sizeof(tk
) < 128 ? sizeof(tk
) : 128;
976 key
= (u_char
*) _KEYBUF(state
->sav
->key_auth
);
977 keylen
= _KEYLEN(state
->sav
->key_auth
);
982 bcopy(key
, ipad
, keylen
);
983 bcopy(key
, opad
, keylen
);
984 for (i
= 0; i
< 128; i
++) {
989 bzero(ctxt
, sizeof(*ctxt
));
991 SHA384_Update(ctxt
, ipad
, 128);
997 ah_hmac_sha2_384_loop(state
, addr
, len
)
998 struct ah_algorithm_state
*state
;
1004 if (!state
|| !state
->foo
)
1005 panic("ah_hmac_sha2_384_loop: what?");
1007 ctxt
= (SHA384_CTX
*)(((u_char
*)state
->foo
) + 256);
1008 SHA384_Update(ctxt
, (const u_int8_t
*)addr
, (size_t)len
);
1012 ah_hmac_sha2_384_result(state
, addr
)
1013 struct ah_algorithm_state
*state
;
1020 if (!state
|| !state
->foo
)
1021 panic("ah_hmac_sha2_384_result: what?");
1023 ipad
= (u_char
*)state
->foo
;
1024 opad
= (u_char
*)(ipad
+ 128);
1025 ctxt
= (SHA384_CTX
*)(opad
+ 128);
1027 SHA384_Final((u_int8_t
*)addr
, ctxt
);
1029 bzero(ctxt
, sizeof(*ctxt
));
1031 SHA384_Update(ctxt
, opad
, 128);
1032 SHA384_Update(ctxt
, (const u_int8_t
*)addr
, SHA384_DIGEST_LENGTH
);
1033 SHA384_Final((u_int8_t
*)addr
, ctxt
);
1035 FREE(state
->foo
, M_TEMP
);
1039 ah_sumsiz_sha2_512(sav
)
1040 struct secasvar
*sav
;
1044 // return half the output size (in bytes), as per rfc 4868
1045 return 32; // 512/(8*2)
1049 ah_hmac_sha2_512_mature(sav
)
1050 struct secasvar
*sav
;
1052 const struct ah_algorithm
*algo
;
1054 if (!sav
->key_auth
) {
1056 "ah_hmac_sha2_512_mature: no key is given.\n"));
1060 algo
= ah_algorithm_lookup(sav
->alg_auth
);
1063 "ah_hmac_sha2_512_mature: unsupported algorithm.\n"));
1067 if (sav
->key_auth
->sadb_key_bits
< algo
->keymin
||
1068 algo
->keymax
< sav
->key_auth
->sadb_key_bits
) {
1070 "ah_hmac_sha2_512_mature: invalid key length %d.\n",
1071 sav
->key_auth
->sadb_key_bits
));
1079 ah_hmac_sha2_512_init(state
, sav
)
1080 struct ah_algorithm_state
*state
;
1081 struct secasvar
*sav
;
1086 u_char tk
[SHA512_DIGEST_LENGTH
];
1092 panic("ah_hmac_sha2_512_init: what?");
1095 state
->foo
= (void *)_MALLOC(128 + 128 + sizeof(SHA512_CTX
),
1099 bzero(state
->foo
, 128 + 128 + sizeof(SHA512_CTX
));
1101 ipad
= (u_char
*)state
->foo
;
1102 opad
= (u_char
*)(ipad
+ 128);
1103 ctxt
= (SHA512_CTX
*)(opad
+ 128);
1105 /* compress the key if necessery */
1106 if (128 < _KEYLEN(state
->sav
->key_auth
)) {
1107 bzero(tk
, sizeof(tk
));
1108 bzero(ctxt
, sizeof(*ctxt
));
1110 SHA512_Update(ctxt
, (const u_int8_t
*) _KEYBUF(state
->sav
->key_auth
),
1111 _KEYLEN(state
->sav
->key_auth
));
1112 SHA512_Final(&tk
[0], ctxt
);
1114 keylen
= sizeof(tk
) < 128 ? sizeof(tk
) : 128;
1116 key
= (u_char
*) _KEYBUF(state
->sav
->key_auth
);
1117 keylen
= _KEYLEN(state
->sav
->key_auth
);
1122 bcopy(key
, ipad
, keylen
);
1123 bcopy(key
, opad
, keylen
);
1124 for (i
= 0; i
< 128; i
++) {
1129 bzero(ctxt
, sizeof(*ctxt
));
1131 SHA512_Update(ctxt
, ipad
, 128);
1137 ah_hmac_sha2_512_loop(state
, addr
, len
)
1138 struct ah_algorithm_state
*state
;
1144 if (!state
|| !state
->foo
)
1145 panic("ah_hmac_sha2_512_loop: what?");
1147 ctxt
= (SHA512_CTX
*)(((u_char
*)state
->foo
) + 256);
1148 SHA512_Update(ctxt
, (const u_int8_t
*) addr
, (size_t)len
);
1152 ah_hmac_sha2_512_result(state
, addr
)
1153 struct ah_algorithm_state
*state
;
1160 if (!state
|| !state
->foo
)
1161 panic("ah_hmac_sha2_512_result: what?");
1163 ipad
= (u_char
*)state
->foo
;
1164 opad
= (u_char
*)(ipad
+ 128);
1165 ctxt
= (SHA512_CTX
*)(opad
+ 128);
1167 SHA512_Final((u_int8_t
*)addr
, ctxt
);
1169 bzero(ctxt
, sizeof(*ctxt
));
1171 SHA512_Update(ctxt
, opad
, 128);
1172 SHA512_Update(ctxt
, (const u_int8_t
*)addr
, SHA512_DIGEST_LENGTH
);
1173 SHA512_Final((u_int8_t
*)addr
, ctxt
);
1175 FREE(state
->foo
, M_TEMP
);
1177 #endif /* ALLCRYPTO */
1179 /*------------------------------------------------------------*/
1182 * go generate the checksum.
1185 ah_update_mbuf(m
, off
, len
, algo
, algos
)
1189 const struct ah_algorithm
*algo
;
1190 struct ah_algorithm_state
*algos
;
1195 /* easy case first */
1196 if (off
+ len
<= m
->m_len
) {
1197 (algo
->update
)(algos
, mtod(m
, caddr_t
) + off
, len
);
1201 for (n
= m
; n
; n
= n
->m_next
) {
1209 panic("ah_update_mbuf: wrong offset specified");
1211 for (/*nothing*/; n
&& len
> 0; n
= n
->m_next
) {
1214 if (n
->m_len
- off
< len
)
1215 tlen
= n
->m_len
- off
;
1219 (algo
->update
)(algos
, mtod(n
, caddr_t
) + off
, tlen
);
1228 * Go generate the checksum. This function won't modify the mbuf chain
1231 * NOTE: the function does not free mbuf on failure.
1232 * Don't use m_copy(), it will try to share cluster mbuf by using refcnt.
1235 ah4_calccksum(m
, ahdat
, len
, algo
, sav
)
1239 const struct ah_algorithm
*algo
;
1240 struct secasvar
*sav
;
1244 size_t advancewidth
;
1245 struct ah_algorithm_state algos
;
1246 u_char sumbuf
[AH_MAXSUMSIZE
];
1249 struct mbuf
*n
= NULL
;
1251 if ((m
->m_flags
& M_PKTHDR
) == 0)
1255 hdrtype
= -1; /*dummy, it is called IPPROTO_IP*/
1259 error
= (algo
->init
)(&algos
, sav
);
1263 advancewidth
= 0; /*safety*/
1268 case -1: /*first one only*/
1271 * copy ip hdr, modify to fit the AH checksum rule,
1272 * then take a checksum.
1277 m_copydata(m
, off
, sizeof(iphdr
), (caddr_t
)&iphdr
);
1279 hlen
= IP_VHL_HL(iphdr
.ip_vhl
) << 2;
1281 hlen
= iphdr
.ip_hl
<< 2;
1284 iphdr
.ip_sum
= htons(0);
1285 if (ip4_ah_cleartos
)
1287 iphdr
.ip_off
= htons(ntohs(iphdr
.ip_off
) & ip4_ah_offsetmask
);
1288 (algo
->update
)(&algos
, (caddr_t
)&iphdr
, sizeof(struct ip
));
1290 if (hlen
!= sizeof(struct ip
)) {
1294 if (hlen
> MCLBYTES
) {
1298 MGET(n
, M_DONTWAIT
, MT_DATA
);
1299 if (n
&& hlen
> MLEN
) {
1300 MCLGET(n
, M_DONTWAIT
);
1301 if ((n
->m_flags
& M_EXT
) == 0) {
1310 m_copydata(m
, off
, hlen
, mtod(n
, caddr_t
));
1313 * IP options processing.
1314 * See RFC2402 appendix A.
1316 p
= mtod(n
, u_char
*);
1317 i
= sizeof(struct ip
);
1319 if (i
+ IPOPT_OPTVAL
>= hlen
) {
1320 ipseclog((LOG_ERR
, "ah4_calccksum: "
1321 "invalid IP option\n"));
1325 if (p
[i
+ IPOPT_OPTVAL
] == IPOPT_EOL
||
1326 p
[i
+ IPOPT_OPTVAL
] == IPOPT_NOP
||
1327 i
+ IPOPT_OLEN
< hlen
)
1331 "ah4_calccksum: invalid IP option "
1333 p
[i
+ IPOPT_OPTVAL
]));
1339 switch (p
[i
+ IPOPT_OPTVAL
]) {
1345 case IPOPT_SECURITY
: /* 0x82 */
1346 case 0x85: /* Extended security */
1347 case 0x86: /* Commercial security */
1348 case 0x94: /* Router alert */
1349 case 0x95: /* RFC1770 */
1350 l
= p
[i
+ IPOPT_OLEN
];
1356 l
= p
[i
+ IPOPT_OLEN
];
1362 if (l
< 1 || hlen
- i
< l
) {
1365 "ah4_calccksum: invalid IP option "
1366 "(type=%02x len=%02x)\n",
1367 p
[i
+ IPOPT_OPTVAL
],
1368 p
[i
+ IPOPT_OLEN
]));
1374 if (p
[i
+ IPOPT_OPTVAL
] == IPOPT_EOL
)
1379 p
= mtod(n
, u_char
*) + sizeof(struct ip
);
1380 (algo
->update
)(&algos
, (caddr_t
)p
, hlen
- sizeof(struct ip
));
1386 hdrtype
= (iphdr
.ip_p
) & 0xff;
1387 advancewidth
= hlen
;
1398 m_copydata(m
, off
, sizeof(ah
), (caddr_t
)&ah
);
1399 hdrsiz
= (sav
->flags
& SADB_X_EXT_OLD
)
1401 : sizeof(struct newah
);
1402 siz
= (*algo
->sumsiz
)(sav
);
1403 totlen
= (ah
.ah_len
+ 2) << 2;
1406 * special treatment is necessary for the first one, not others
1409 if (totlen
> m
->m_pkthdr
.len
- off
||
1410 totlen
> MCLBYTES
) {
1414 MGET(n
, M_DONTWAIT
, MT_DATA
);
1415 if (n
&& totlen
> MLEN
) {
1416 MCLGET(n
, M_DONTWAIT
);
1417 if ((n
->m_flags
& M_EXT
) == 0) {
1426 m_copydata(m
, off
, totlen
, mtod(n
, caddr_t
));
1428 bzero(mtod(n
, caddr_t
) + hdrsiz
, siz
);
1429 (algo
->update
)(&algos
, mtod(n
, caddr_t
), n
->m_len
);
1433 ah_update_mbuf(m
, off
, totlen
, algo
, &algos
);
1436 hdrtype
= ah
.ah_nxt
;
1437 advancewidth
= totlen
;
1442 ah_update_mbuf(m
, off
, m
->m_pkthdr
.len
- off
, algo
, &algos
);
1443 advancewidth
= m
->m_pkthdr
.len
- off
;
1447 off
+= advancewidth
;
1448 if (off
< m
->m_pkthdr
.len
)
1451 if (len
< (*algo
->sumsiz
)(sav
)) {
1456 (algo
->result
)(&algos
, (caddr_t
) &sumbuf
[0]);
1457 bcopy(&sumbuf
[0], ahdat
, (*algo
->sumsiz
)(sav
));
1472 * Go generate the checksum. This function won't modify the mbuf chain
1475 * NOTE: the function does not free mbuf on failure.
1476 * Don't use m_copy(), it will try to share cluster mbuf by using refcnt.
1479 ah6_calccksum(m
, ahdat
, len
, algo
, sav
)
1483 const struct ah_algorithm
*algo
;
1484 struct secasvar
*sav
;
1488 struct mbuf
*n
= NULL
;
1491 struct ah_algorithm_state algos
;
1492 u_char sumbuf
[AH_MAXSUMSIZE
];
1494 if ((m
->m_flags
& M_PKTHDR
) == 0)
1497 error
= (algo
->init
)(&algos
, sav
);
1502 proto
= IPPROTO_IPV6
;
1507 newoff
= ip6_nexthdr(m
, off
, proto
, &nxt
);
1509 newoff
= m
->m_pkthdr
.len
;
1510 else if (newoff
<= off
) {
1518 * special treatment is necessary for the first one, not others
1521 struct ip6_hdr ip6copy
;
1523 if (newoff
- off
!= sizeof(struct ip6_hdr
)) {
1528 m_copydata(m
, off
, newoff
- off
, (caddr_t
)&ip6copy
);
1530 ip6copy
.ip6_flow
= 0;
1531 ip6copy
.ip6_vfc
&= ~IPV6_VERSION_MASK
;
1532 ip6copy
.ip6_vfc
|= IPV6_VERSION
;
1533 ip6copy
.ip6_hlim
= 0;
1534 if (IN6_IS_ADDR_LINKLOCAL(&ip6copy
.ip6_src
))
1535 ip6copy
.ip6_src
.s6_addr16
[1] = 0x0000;
1536 if (IN6_IS_ADDR_LINKLOCAL(&ip6copy
.ip6_dst
))
1537 ip6copy
.ip6_dst
.s6_addr16
[1] = 0x0000;
1538 (algo
->update
)(&algos
, (caddr_t
)&ip6copy
,
1539 sizeof(struct ip6_hdr
));
1541 newoff
= m
->m_pkthdr
.len
;
1542 ah_update_mbuf(m
, off
, m
->m_pkthdr
.len
- off
, algo
,
1552 hdrsiz
= (sav
->flags
& SADB_X_EXT_OLD
)
1554 : sizeof(struct newah
);
1555 siz
= (*algo
->sumsiz
)(sav
);
1558 * special treatment is necessary for the first one, not others
1561 if (newoff
- off
> MCLBYTES
) {
1565 MGET(n
, M_DONTWAIT
, MT_DATA
);
1566 if (n
&& newoff
- off
> MLEN
) {
1567 MCLGET(n
, M_DONTWAIT
);
1568 if ((n
->m_flags
& M_EXT
) == 0) {
1577 m_copydata(m
, off
, newoff
- off
, mtod(n
, caddr_t
));
1578 n
->m_len
= newoff
- off
;
1579 bzero(mtod(n
, caddr_t
) + hdrsiz
, siz
);
1580 (algo
->update
)(&algos
, mtod(n
, caddr_t
), n
->m_len
);
1584 ah_update_mbuf(m
, off
, newoff
- off
, algo
, &algos
);
1589 case IPPROTO_HOPOPTS
:
1590 case IPPROTO_DSTOPTS
:
1592 struct ip6_ext
*ip6e
;
1594 u_int8_t
*p
, *optend
, *optp
;
1596 if (newoff
- off
> MCLBYTES
) {
1600 MGET(n
, M_DONTWAIT
, MT_DATA
);
1601 if (n
&& newoff
- off
> MLEN
) {
1602 MCLGET(n
, M_DONTWAIT
);
1603 if ((n
->m_flags
& M_EXT
) == 0) {
1612 m_copydata(m
, off
, newoff
- off
, mtod(n
, caddr_t
));
1613 n
->m_len
= newoff
- off
;
1615 ip6e
= mtod(n
, struct ip6_ext
*);
1616 hdrlen
= (ip6e
->ip6e_len
+ 1) << 3;
1617 if (newoff
- off
< hdrlen
) {
1623 p
= mtod(n
, u_int8_t
*);
1624 optend
= p
+ hdrlen
;
1627 * ICV calculation for the options header including all
1628 * options. This part is a little tricky since there are
1629 * two type of options; mutable and immutable. We try to
1630 * null-out mutable ones here.
1633 while (optp
< optend
) {
1634 if (optp
[0] == IP6OPT_PAD1
)
1637 if (optp
+ 2 > optend
) {
1643 optlen
= optp
[1] + 2;
1645 if (optp
[0] & IP6OPT_MUTABLE
)
1646 bzero(optp
+ 2, optlen
- 2);
1652 (algo
->update
)(&algos
, mtod(n
, caddr_t
), n
->m_len
);
1658 case IPPROTO_ROUTING
:
1660 * For an input packet, we can just calculate `as is'.
1661 * For an output packet, we assume ip6_output have already
1662 * made packet how it will be received at the final
1668 ah_update_mbuf(m
, off
, newoff
- off
, algo
, &algos
);
1672 if (newoff
< m
->m_pkthdr
.len
) {
1678 if (len
< (*algo
->sumsiz
)(sav
)) {
1683 (algo
->result
)(&algos
, (caddr_t
) &sumbuf
[0]);
1684 bcopy(&sumbuf
[0], ahdat
, (*algo
->sumsiz
)(sav
));