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