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