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