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