1 /* $FreeBSD: src/sys/netinet6/esp_core.c,v 1.1.2.4 2002/03/26 10:12:29 ume Exp $ */
2 /* $DragonFly: src/sys/netinet6/esp_core.c,v 1.7 2004/06/02 14:43:01 eirikn Exp $ */
3 /* $KAME: esp_core.c,v 1.50 2000/11/02 12:27:38 itojun Exp $ */
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 #include "opt_inet6.h"
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/malloc.h>
41 #include <sys/domain.h>
42 #include <sys/protosw.h>
43 #include <sys/socket.h>
44 #include <sys/errno.h>
46 #include <sys/syslog.h>
49 #include <net/route.h>
51 #include <netinet/in.h>
52 #include <netinet/in_var.h>
54 #include <netinet/ip6.h>
55 #include <netinet6/ip6_var.h>
56 #include <netinet/icmp6.h>
59 #include <netinet6/ipsec.h>
61 #include <netinet6/ipsec6.h>
63 #include <netinet6/ah.h>
65 #include <netinet6/ah6.h>
67 #include <netinet6/esp.h>
69 #include <netinet6/esp6.h>
71 #include <netinet6/esp_rijndael.h>
72 #include <net/pfkeyv2.h>
73 #include <netproto/key/keydb.h>
74 #include <netproto/key/key.h>
75 #include <crypto/des/des.h>
76 #include <crypto/blowfish/blowfish.h>
77 #include <crypto/cast128/cast128.h>
79 #include <net/net_osdep.h>
81 static int esp_null_mature (struct secasvar
*);
82 static int esp_null_decrypt (struct mbuf
*, size_t,
83 struct secasvar
*, const struct esp_algorithm
*, int);
84 static int esp_null_encrypt (struct mbuf
*, size_t, size_t,
85 struct secasvar
*, const struct esp_algorithm
*, int);
86 static int esp_descbc_mature (struct secasvar
*);
87 static int esp_descbc_ivlen (const struct esp_algorithm
*,
89 static int esp_des_schedule (const struct esp_algorithm
*,
91 static int esp_des_schedlen (const struct esp_algorithm
*);
92 static int esp_des_blockdecrypt (const struct esp_algorithm
*,
93 struct secasvar
*, u_int8_t
*, u_int8_t
*);
94 static int esp_des_blockencrypt (const struct esp_algorithm
*,
95 struct secasvar
*, u_int8_t
*, u_int8_t
*);
96 static int esp_cbc_mature (struct secasvar
*);
97 static int esp_blowfish_schedule (const struct esp_algorithm
*,
99 static int esp_blowfish_schedlen (const struct esp_algorithm
*);
100 static int esp_blowfish_blockdecrypt (const struct esp_algorithm
*,
101 struct secasvar
*, u_int8_t
*, u_int8_t
*);
102 static int esp_blowfish_blockencrypt (const struct esp_algorithm
*,
103 struct secasvar
*, u_int8_t
*, u_int8_t
*);
104 static int esp_cast128_schedule (const struct esp_algorithm
*,
106 static int esp_cast128_schedlen (const struct esp_algorithm
*);
107 static int esp_cast128_blockdecrypt (const struct esp_algorithm
*,
108 struct secasvar
*, u_int8_t
*, u_int8_t
*);
109 static int esp_cast128_blockencrypt (const struct esp_algorithm
*,
110 struct secasvar
*, u_int8_t
*, u_int8_t
*);
111 static int esp_3des_schedule (const struct esp_algorithm
*,
113 static int esp_3des_schedlen (const struct esp_algorithm
*);
114 static int esp_3des_blockdecrypt (const struct esp_algorithm
*,
115 struct secasvar
*, u_int8_t
*, u_int8_t
*);
116 static int esp_3des_blockencrypt (const struct esp_algorithm
*,
117 struct secasvar
*, u_int8_t
*, u_int8_t
*);
118 static int esp_common_ivlen (const struct esp_algorithm
*,
120 static int esp_cbc_decrypt (struct mbuf
*, size_t,
121 struct secasvar
*, const struct esp_algorithm
*, int);
122 static int esp_cbc_encrypt (struct mbuf
*, size_t, size_t,
123 struct secasvar
*, const struct esp_algorithm
*, int);
127 static const struct esp_algorithm esp_algorithms
[] = {
128 { 8, -1, esp_descbc_mature
, 64, 64, esp_des_schedlen
,
130 esp_descbc_ivlen
, esp_cbc_decrypt
,
131 esp_cbc_encrypt
, esp_des_schedule
,
132 esp_des_blockdecrypt
, esp_des_blockencrypt
, },
133 { 8, 8, esp_cbc_mature
, 192, 192, esp_3des_schedlen
,
135 esp_common_ivlen
, esp_cbc_decrypt
,
136 esp_cbc_encrypt
, esp_3des_schedule
,
137 esp_3des_blockdecrypt
, esp_3des_blockencrypt
, },
138 { 1, 0, esp_null_mature
, 0, 2048, 0, "null",
139 esp_common_ivlen
, esp_null_decrypt
,
140 esp_null_encrypt
, NULL
, },
141 { 8, 8, esp_cbc_mature
, 40, 448, esp_blowfish_schedlen
, "blowfish-cbc",
142 esp_common_ivlen
, esp_cbc_decrypt
,
143 esp_cbc_encrypt
, esp_blowfish_schedule
,
144 esp_blowfish_blockdecrypt
, esp_blowfish_blockencrypt
, },
145 { 8, 8, esp_cbc_mature
, 40, 128, esp_cast128_schedlen
,
147 esp_common_ivlen
, esp_cbc_decrypt
,
148 esp_cbc_encrypt
, esp_cast128_schedule
,
149 esp_cast128_blockdecrypt
, esp_cast128_blockencrypt
, },
150 { 16, 16, esp_cbc_mature
, 128, 256, esp_rijndael_schedlen
,
152 esp_common_ivlen
, esp_cbc_decrypt
,
153 esp_cbc_encrypt
, esp_rijndael_schedule
,
154 esp_rijndael_blockdecrypt
, esp_rijndael_blockencrypt
},
157 const struct esp_algorithm
*
158 esp_algorithm_lookup(int idx
)
162 case SADB_EALG_DESCBC
:
163 return &esp_algorithms
[0];
164 case SADB_EALG_3DESCBC
:
165 return &esp_algorithms
[1];
167 return &esp_algorithms
[2];
168 case SADB_X_EALG_BLOWFISHCBC
:
169 return &esp_algorithms
[3];
170 case SADB_X_EALG_CAST128CBC
:
171 return &esp_algorithms
[4];
172 case SADB_X_EALG_RIJNDAELCBC
:
173 return &esp_algorithms
[5];
186 for (idx
= 0; idx
< sizeof(esp_algorithms
)/sizeof(esp_algorithms
[0]);
188 if (esp_algorithms
[idx
].ivlenval
> ivlen
)
189 ivlen
= esp_algorithms
[idx
].ivlenval
;
196 esp_schedule(const struct esp_algorithm
*algo
, struct secasvar
*sav
)
200 /* check for key length */
201 if (_KEYBITS(sav
->key_enc
) < algo
->keymin
||
202 _KEYBITS(sav
->key_enc
) > algo
->keymax
) {
204 "esp_schedule %s: unsupported key length %d: "
205 "needs %d to %d bits\n", algo
->name
, _KEYBITS(sav
->key_enc
),
206 algo
->keymin
, algo
->keymax
));
210 /* already allocated */
211 if (sav
->sched
&& sav
->schedlen
!= 0)
213 /* no schedule necessary */
214 if (!algo
->schedule
|| !algo
->schedlen
)
217 sav
->schedlen
= (*algo
->schedlen
)(algo
);
218 if (sav
->schedlen
< 0)
220 sav
->sched
= malloc(sav
->schedlen
, M_SECA
, M_NOWAIT
);
226 error
= (*algo
->schedule
)(algo
, sav
);
228 ipseclog((LOG_ERR
, "esp_schedule %s: error %d\n",
230 free(sav
->sched
, M_SECA
);
238 esp_null_mature(struct secasvar
*sav
)
241 /* anything is okay */
246 esp_null_decrypt(struct mbuf
*m
,
247 size_t off
, /* offset to ESP header */
248 struct secasvar
*sav
, const struct esp_algorithm
*algo
,
252 return 0; /* do nothing */
256 esp_null_encrypt(struct mbuf
*m
,
257 size_t off
, /* offset to ESP header */
258 size_t plen
, struct secasvar
*sav
,
259 const struct esp_algorithm
*algo
, int ivlen
)
262 return 0; /* do nothing */
266 esp_descbc_mature(struct secasvar
*sav
)
268 const struct esp_algorithm
*algo
;
270 if (!(sav
->flags
& SADB_X_EXT_OLD
) && (sav
->flags
& SADB_X_EXT_IV4B
)) {
271 ipseclog((LOG_ERR
, "esp_cbc_mature: "
272 "algorithm incompatible with 4 octets IV length\n"));
277 ipseclog((LOG_ERR
, "esp_descbc_mature: no key is given.\n"));
281 algo
= esp_algorithm_lookup(sav
->alg_enc
);
284 "esp_descbc_mature: unsupported algorithm.\n"));
288 if (_KEYBITS(sav
->key_enc
) < algo
->keymin
||
289 _KEYBITS(sav
->key_enc
) > algo
->keymax
) {
291 "esp_descbc_mature: invalid key length %d.\n",
292 _KEYBITS(sav
->key_enc
)));
297 if (des_is_weak_key((des_cblock
*)_KEYBUF(sav
->key_enc
))) {
299 "esp_descbc_mature: weak key was passed.\n"));
307 esp_descbc_ivlen(const struct esp_algorithm
*algo
, struct secasvar
*sav
)
312 if ((sav
->flags
& SADB_X_EXT_OLD
) && (sav
->flags
& SADB_X_EXT_IV4B
))
314 if (!(sav
->flags
& SADB_X_EXT_OLD
) && (sav
->flags
& SADB_X_EXT_DERIV
))
320 esp_des_schedlen(const struct esp_algorithm
*algo
)
323 return sizeof(des_key_schedule
);
327 esp_des_schedule(const struct esp_algorithm
*algo
, struct secasvar
*sav
)
330 if (des_key_sched((des_cblock
*)_KEYBUF(sav
->key_enc
),
331 *(des_key_schedule
*)sav
->sched
))
338 esp_des_blockdecrypt(const struct esp_algorithm
*algo
, struct secasvar
*sav
,
339 u_int8_t
*s
, u_int8_t
*d
)
342 /* assumption: d has a good alignment */
343 bcopy(s
, d
, sizeof(DES_LONG
) * 2);
344 des_ecb_encrypt((des_cblock
*)d
, (des_cblock
*)d
,
345 *(des_key_schedule
*)sav
->sched
, DES_DECRYPT
);
350 esp_des_blockencrypt(const struct esp_algorithm
*algo
, struct secasvar
*sav
,
351 u_int8_t
*s
, u_int8_t
*d
)
354 /* assumption: d has a good alignment */
355 bcopy(s
, d
, sizeof(DES_LONG
) * 2);
356 des_ecb_encrypt((des_cblock
*)d
, (des_cblock
*)d
,
357 *(des_key_schedule
*)sav
->sched
, DES_ENCRYPT
);
362 esp_cbc_mature(struct secasvar
*sav
)
365 const struct esp_algorithm
*algo
;
367 if (sav
->flags
& SADB_X_EXT_OLD
) {
369 "esp_cbc_mature: algorithm incompatible with esp-old\n"));
372 if (sav
->flags
& SADB_X_EXT_DERIV
) {
374 "esp_cbc_mature: algorithm incompatible with derived\n"));
379 ipseclog((LOG_ERR
, "esp_cbc_mature: no key is given.\n"));
383 algo
= esp_algorithm_lookup(sav
->alg_enc
);
386 "esp_cbc_mature %s: unsupported algorithm.\n", algo
->name
));
390 keylen
= sav
->key_enc
->sadb_key_bits
;
391 if (keylen
< algo
->keymin
|| algo
->keymax
< keylen
) {
393 "esp_cbc_mature %s: invalid key length %d.\n",
394 algo
->name
, sav
->key_enc
->sadb_key_bits
));
397 switch (sav
->alg_enc
) {
398 case SADB_EALG_3DESCBC
:
400 if (des_is_weak_key((des_cblock
*)_KEYBUF(sav
->key_enc
)) ||
401 des_is_weak_key((des_cblock
*)(_KEYBUF(sav
->key_enc
) + 8)) ||
402 des_is_weak_key((des_cblock
*)(_KEYBUF(sav
->key_enc
) + 16))) {
404 "esp_cbc_mature %s: weak key was passed.\n",
409 case SADB_X_EALG_BLOWFISHCBC
:
410 case SADB_X_EALG_CAST128CBC
:
412 case SADB_X_EALG_RIJNDAELCBC
:
413 /* allows specific key sizes only */
414 if (!(keylen
== 128 || keylen
== 192 || keylen
== 256)) {
416 "esp_cbc_mature %s: invalid key length %d.\n",
417 algo
->name
, keylen
));
427 esp_blowfish_schedlen(const struct esp_algorithm
*algo
)
430 return sizeof(BF_KEY
);
434 esp_blowfish_schedule(const struct esp_algorithm
*algo
, struct secasvar
*sav
)
437 BF_set_key((BF_KEY
*)sav
->sched
, _KEYLEN(sav
->key_enc
),
438 _KEYBUF(sav
->key_enc
));
443 esp_blowfish_blockdecrypt(const struct esp_algorithm
*algo
,
444 struct secasvar
*sav
, u_int8_t
*s
, u_int8_t
*d
)
446 /* HOLY COW! BF_decrypt() takes values in host byteorder */
449 bcopy(s
, t
, sizeof(t
));
452 BF_decrypt(t
, (BF_KEY
*)sav
->sched
);
455 bcopy(t
, d
, sizeof(t
));
460 esp_blowfish_blockencrypt(const struct esp_algorithm
*algo
,
461 struct secasvar
*sav
, u_int8_t
*s
, u_int8_t
*d
)
463 /* HOLY COW! BF_encrypt() takes values in host byteorder */
466 bcopy(s
, t
, sizeof(t
));
469 BF_encrypt(t
, (BF_KEY
*)sav
->sched
);
472 bcopy(t
, d
, sizeof(t
));
477 esp_cast128_schedlen(const struct esp_algorithm
*algo
)
480 return sizeof(u_int32_t
) * 32;
484 esp_cast128_schedule(const struct esp_algorithm
*algo
, struct secasvar
*sav
)
487 set_cast128_subkey((u_int32_t
*)sav
->sched
, _KEYBUF(sav
->key_enc
),
488 _KEYLEN(sav
->key_enc
));
493 esp_cast128_blockdecrypt(const struct esp_algorithm
*algo
,
494 struct secasvar
*sav
, u_int8_t
*s
, u_int8_t
*d
)
497 if (_KEYLEN(sav
->key_enc
) <= 80 / 8)
498 cast128_decrypt_round12(d
, s
, (u_int32_t
*)sav
->sched
);
500 cast128_decrypt_round16(d
, s
, (u_int32_t
*)sav
->sched
);
505 esp_cast128_blockencrypt(const struct esp_algorithm
*algo
, struct secasvar
*sav
,
506 u_int8_t
*s
, u_int8_t
*d
)
509 if (_KEYLEN(sav
->key_enc
) <= 80 / 8)
510 cast128_encrypt_round12(d
, s
, (u_int32_t
*)sav
->sched
);
512 cast128_encrypt_round16(d
, s
, (u_int32_t
*)sav
->sched
);
517 esp_3des_schedlen(const struct esp_algorithm
*algo
)
520 return sizeof(des_key_schedule
) * 3;
524 esp_3des_schedule(const struct esp_algorithm
*algo
, struct secasvar
*sav
)
531 p
= (des_key_schedule
*)sav
->sched
;
532 k
= _KEYBUF(sav
->key_enc
);
533 for (i
= 0; i
< 3; i
++) {
534 error
= des_key_sched((des_cblock
*)(k
+ 8 * i
), p
[i
]);
542 esp_3des_blockdecrypt(const struct esp_algorithm
*algo
, struct secasvar
*sav
,
543 u_int8_t
*s
, u_int8_t
*d
)
547 /* assumption: d has a good alignment */
548 p
= (des_key_schedule
*)sav
->sched
;
549 bcopy(s
, d
, sizeof(DES_LONG
) * 2);
550 des_ecb3_encrypt((des_cblock
*)d
, (des_cblock
*)d
,
551 p
[0], p
[1], p
[2], DES_DECRYPT
);
556 esp_3des_blockencrypt(const struct esp_algorithm
*algo
, struct secasvar
*sav
,
557 u_int8_t
*s
, u_int8_t
*d
)
561 /* assumption: d has a good alignment */
562 p
= (des_key_schedule
*)sav
->sched
;
563 bcopy(s
, d
, sizeof(DES_LONG
) * 2);
564 des_ecb3_encrypt((des_cblock
*)d
, (des_cblock
*)d
,
565 p
[0], p
[1], p
[2], DES_ENCRYPT
);
570 esp_common_ivlen(const struct esp_algorithm
*algo
, struct secasvar
*sav
)
574 panic("esp_common_ivlen: unknown algorithm");
575 return algo
->ivlenval
;
579 esp_cbc_decrypt(struct mbuf
*m
, size_t off
, struct secasvar
*sav
,
580 const struct esp_algorithm
*algo
, int ivlen
)
583 struct mbuf
*d
, *d0
, *dp
;
584 int soff
, doff
; /* offset from the head of chain, to head of this mbuf */
585 int sn
, dn
; /* offset from the head of the mbuf, to meat */
586 size_t ivoff
, bodyoff
;
587 u_int8_t iv
[MAXIVLEN
], *ivp
;
588 u_int8_t sbuf
[MAXIVLEN
], *sp
;
596 if (ivlen
!= sav
->ivlen
|| ivlen
> sizeof(iv
)) {
597 ipseclog((LOG_ERR
, "esp_cbc_decrypt %s: "
598 "unsupported ivlen %d\n", algo
->name
, ivlen
));
603 /* assumes blocklen == padbound */
604 blocklen
= algo
->padbound
;
607 if (blocklen
> sizeof(iv
)) {
608 ipseclog((LOG_ERR
, "esp_cbc_decrypt %s: "
609 "unsupported blocklen %d\n", algo
->name
, blocklen
));
615 if (sav
->flags
& SADB_X_EXT_OLD
) {
617 ivoff
= off
+ sizeof(struct esp
);
618 bodyoff
= off
+ sizeof(struct esp
) + ivlen
;
622 if (sav
->flags
& SADB_X_EXT_DERIV
) {
624 * draft-ietf-ipsec-ciph-des-derived-00.txt
625 * uses sequence number field as IV field.
627 ivoff
= off
+ sizeof(struct esp
);
628 bodyoff
= off
+ sizeof(struct esp
) + sizeof(u_int32_t
);
629 ivlen
= sizeof(u_int32_t
);
632 ivoff
= off
+ sizeof(struct newesp
);
633 bodyoff
= off
+ sizeof(struct newesp
) + ivlen
;
639 m_copydata(m
, ivoff
, ivlen
, iv
);
642 if (ivlen
== blocklen
)
644 else if (ivlen
== 4 && blocklen
== 8) {
645 bcopy(&iv
[0], &iv
[4], 4);
651 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: "
652 "unsupported ivlen/blocklen: %d %d\n",
653 algo
->name
, ivlen
, blocklen
));
658 if (m
->m_pkthdr
.len
< bodyoff
) {
659 ipseclog((LOG_ERR
, "esp_cbc_decrypt %s: bad len %d/%lu\n",
660 algo
->name
, m
->m_pkthdr
.len
, (unsigned long)bodyoff
));
664 if ((m
->m_pkthdr
.len
- bodyoff
) % blocklen
) {
665 ipseclog((LOG_ERR
, "esp_cbc_decrypt %s: "
666 "payload length must be multiple of %d\n",
667 algo
->name
, blocklen
));
674 soff
= doff
= sn
= dn
= 0;
678 while (soff
< bodyoff
) {
679 if (soff
+ s
->m_len
> bodyoff
) {
690 /* skip over empty mbuf */
691 while (s
&& s
->m_len
== 0)
694 while (soff
< m
->m_pkthdr
.len
) {
696 if (sn
+ blocklen
<= s
->m_len
) {
697 /* body is continuous */
698 sp
= mtod(s
, u_int8_t
*) + sn
;
700 /* body is non-continuous */
701 m_copydata(s
, sn
, blocklen
, sbuf
);
706 if (!d
|| dn
+ blocklen
> d
->m_len
) {
709 MGET(d
, MB_DONTWAIT
, MT_DATA
);
710 i
= m
->m_pkthdr
.len
- (soff
+ sn
);
712 MCLGET(d
, MB_DONTWAIT
);
713 if ((d
->m_flags
& M_EXT
) == 0) {
729 d
->m_len
= (M_TRAILINGSPACE(d
) / blocklen
) * blocklen
;
736 (*algo
->blockdecrypt
)(algo
, sav
, sp
, mtod(d
, u_int8_t
*) + dn
);
740 q
= mtod(d
, u_int8_t
*) + dn
;
741 for (i
= 0; i
< blocklen
; i
++)
746 bcopy(sbuf
, iv
, blocklen
);
754 /* find the next source block */
755 while (s
&& sn
>= s
->m_len
) {
761 /* skip over empty mbuf */
762 while (s
&& s
->m_len
== 0)
766 m_freem(scut
->m_next
);
767 scut
->m_len
= scutoff
;
771 bzero(iv
, sizeof(iv
));
772 bzero(sbuf
, sizeof(sbuf
));
778 esp_cbc_encrypt(struct mbuf
*m
, size_t off
, size_t plen
, struct secasvar
*sav
,
779 const struct esp_algorithm
*algo
, int ivlen
)
782 struct mbuf
*d
, *d0
, *dp
;
783 int soff
, doff
; /* offset from the head of chain, to head of this mbuf */
784 int sn
, dn
; /* offset from the head of the mbuf, to meat */
785 size_t ivoff
, bodyoff
;
786 u_int8_t iv
[MAXIVLEN
], *ivp
;
787 u_int8_t sbuf
[MAXIVLEN
], *sp
;
795 if (ivlen
!= sav
->ivlen
|| ivlen
> sizeof(iv
)) {
796 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: "
797 "unsupported ivlen %d\n", algo
->name
, ivlen
));
802 /* assumes blocklen == padbound */
803 blocklen
= algo
->padbound
;
806 if (blocklen
> sizeof(iv
)) {
807 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: "
808 "unsupported blocklen %d\n", algo
->name
, blocklen
));
814 if (sav
->flags
& SADB_X_EXT_OLD
) {
816 ivoff
= off
+ sizeof(struct esp
);
817 bodyoff
= off
+ sizeof(struct esp
) + ivlen
;
821 if (sav
->flags
& SADB_X_EXT_DERIV
) {
823 * draft-ietf-ipsec-ciph-des-derived-00.txt
824 * uses sequence number field as IV field.
826 ivoff
= off
+ sizeof(struct esp
);
827 bodyoff
= off
+ sizeof(struct esp
) + sizeof(u_int32_t
);
828 ivlen
= sizeof(u_int32_t
);
831 ivoff
= off
+ sizeof(struct newesp
);
832 bodyoff
= off
+ sizeof(struct newesp
) + ivlen
;
837 /* put iv into the packet. if we are in derived mode, use seqno. */
839 m_copydata(m
, ivoff
, ivlen
, iv
);
841 bcopy(sav
->iv
, iv
, ivlen
);
842 /* maybe it is better to overwrite dest, not source */
843 m_copyback(m
, ivoff
, ivlen
, iv
);
847 if (ivlen
== blocklen
)
849 else if (ivlen
== 4 && blocklen
== 8) {
850 bcopy(&iv
[0], &iv
[4], 4);
856 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: "
857 "unsupported ivlen/blocklen: %d %d\n",
858 algo
->name
, ivlen
, blocklen
));
863 if (m
->m_pkthdr
.len
< bodyoff
) {
864 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: bad len %d/%lu\n",
865 algo
->name
, m
->m_pkthdr
.len
, (unsigned long)bodyoff
));
869 if ((m
->m_pkthdr
.len
- bodyoff
) % blocklen
) {
870 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: "
871 "payload length must be multiple of %lu\n",
872 algo
->name
, (unsigned long)algo
->padbound
));
879 soff
= doff
= sn
= dn
= 0;
883 while (soff
< bodyoff
) {
884 if (soff
+ s
->m_len
> bodyoff
) {
895 /* skip over empty mbuf */
896 while (s
&& s
->m_len
== 0)
899 while (soff
< m
->m_pkthdr
.len
) {
901 if (sn
+ blocklen
<= s
->m_len
) {
902 /* body is continuous */
903 sp
= mtod(s
, u_int8_t
*) + sn
;
905 /* body is non-continuous */
906 m_copydata(s
, sn
, blocklen
, sbuf
);
911 if (!d
|| dn
+ blocklen
> d
->m_len
) {
914 MGET(d
, MB_DONTWAIT
, MT_DATA
);
915 i
= m
->m_pkthdr
.len
- (soff
+ sn
);
917 MCLGET(d
, MB_DONTWAIT
);
918 if ((d
->m_flags
& M_EXT
) == 0) {
934 d
->m_len
= (M_TRAILINGSPACE(d
) / blocklen
) * blocklen
;
943 for (i
= 0; i
< blocklen
; i
++)
947 (*algo
->blockencrypt
)(algo
, sav
, sp
, mtod(d
, u_int8_t
*) + dn
);
950 ivp
= mtod(d
, u_int8_t
*) + dn
;
955 /* find the next source block */
956 while (s
&& sn
>= s
->m_len
) {
962 /* skip over empty mbuf */
963 while (s
&& s
->m_len
== 0)
967 m_freem(scut
->m_next
);
968 scut
->m_len
= scutoff
;
972 bzero(iv
, sizeof(iv
));
973 bzero(sbuf
, sizeof(sbuf
));
980 /*------------------------------------------------------------*/
982 /* does not free m0 on error */
984 esp_auth(struct mbuf
*m0
,
985 size_t skip
, /* offset to ESP header */
986 size_t length
, /* payload length */
987 struct secasvar
*sav
, u_char
*sum
)
991 struct ah_algorithm_state s
;
992 u_char sumbuf
[AH_MAXSUMSIZE
];
993 const struct ah_algorithm
*algo
;
998 if (m0
->m_pkthdr
.len
< skip
) {
999 ipseclog((LOG_DEBUG
, "esp_auth: mbuf length < skip\n"));
1002 if (m0
->m_pkthdr
.len
< skip
+ length
) {
1003 ipseclog((LOG_DEBUG
,
1004 "esp_auth: mbuf length < skip + length\n"));
1008 * length of esp part (excluding authentication data) must be 4n,
1009 * since nexthdr must be at offset 4n+3.
1012 ipseclog((LOG_ERR
, "esp_auth: length is not multiple of 4\n"));
1016 ipseclog((LOG_DEBUG
, "esp_auth: NULL SA passed\n"));
1019 algo
= ah_algorithm_lookup(sav
->alg_auth
);
1022 "esp_auth: bad ESP auth algorithm passed: %d\n",
1030 siz
= (((*algo
->sumsiz
)(sav
) + 3) & ~(4 - 1));
1031 if (sizeof(sumbuf
) < siz
) {
1032 ipseclog((LOG_DEBUG
,
1033 "esp_auth: AH_MAXSUMSIZE is too small: siz=%lu\n",
1038 /* skip the header */
1041 panic("mbuf chain?");
1042 if (m
->m_len
<= skip
) {
1052 error
= (*algo
->init
)(&s
, sav
);
1056 while (0 < length
) {
1058 panic("mbuf chain?");
1060 if (m
->m_len
- off
< length
) {
1061 (*algo
->update
)(&s
, mtod(m
, u_char
*) + off
,
1063 length
-= m
->m_len
- off
;
1067 (*algo
->update
)(&s
, mtod(m
, u_char
*) + off
, length
);
1071 (*algo
->result
)(&s
, sumbuf
);
1072 bcopy(sumbuf
, sum
, siz
); /* XXX */