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