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