1 /* $NetBSD: esp_core.c,v 1.44 2009/03/18 17:06:52 cegger Exp $ */
2 /* $KAME: esp_core.c,v 1.53 2001/11/27 09:47:30 sakane Exp $ */
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: esp_core.c,v 1.44 2009/03/18 17:06:52 cegger Exp $");
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/malloc.h>
42 #include <sys/domain.h>
43 #include <sys/protosw.h>
44 #include <sys/socket.h>
45 #include <sys/errno.h>
47 #include <sys/kernel.h>
48 #include <sys/syslog.h>
51 #include <net/route.h>
53 #include <netinet/in.h>
55 #include <netinet6/ipsec.h>
56 #include <netinet6/ah.h>
57 #include <netinet6/esp.h>
58 #include <netinet6/esp_rijndael.h>
59 #include <netinet6/esp_aesctr.h>
60 #include <net/pfkeyv2.h>
61 #include <netkey/key.h>
63 #include <crypto/des/des.h>
64 #include <crypto/blowfish/blowfish.h>
65 #include <crypto/cast128/cast128.h>
67 #include <net/net_osdep.h>
69 static int esp_null_mature(struct secasvar
*);
70 static int esp_null_decrypt(struct mbuf
*, size_t,
71 struct secasvar
*, const struct esp_algorithm
*, int);
72 static int esp_null_encrypt(struct mbuf
*, size_t, size_t,
73 struct secasvar
*, const struct esp_algorithm
*, int);
74 static int esp_descbc_mature(struct secasvar
*);
75 static int esp_descbc_ivlen(const struct esp_algorithm
*,
77 static int esp_des_schedule(const struct esp_algorithm
*,
79 static size_t esp_des_schedlen(const struct esp_algorithm
*);
80 static int esp_des_blockdecrypt(const struct esp_algorithm
*,
81 struct secasvar
*, u_int8_t
*, u_int8_t
*);
82 static int esp_des_blockencrypt(const struct esp_algorithm
*,
83 struct secasvar
*, u_int8_t
*, u_int8_t
*);
84 static int esp_cbc_mature(struct secasvar
*);
85 static int esp_blowfish_schedule(const struct esp_algorithm
*,
87 static size_t esp_blowfish_schedlen(const struct esp_algorithm
*);
88 static int esp_blowfish_blockdecrypt(const struct esp_algorithm
*,
89 struct secasvar
*, u_int8_t
*, u_int8_t
*);
90 static int esp_blowfish_blockencrypt(const struct esp_algorithm
*,
91 struct secasvar
*, u_int8_t
*, u_int8_t
*);
92 static int esp_cast128_schedule(const struct esp_algorithm
*,
94 static size_t esp_cast128_schedlen(const struct esp_algorithm
*);
95 static int esp_cast128_blockdecrypt(const struct esp_algorithm
*,
96 struct secasvar
*, u_int8_t
*, u_int8_t
*);
97 static int esp_cast128_blockencrypt(const struct esp_algorithm
*,
98 struct secasvar
*, u_int8_t
*, u_int8_t
*);
99 static int esp_3des_schedule(const struct esp_algorithm
*,
101 static size_t esp_3des_schedlen(const struct esp_algorithm
*);
102 static int esp_3des_blockdecrypt(const struct esp_algorithm
*,
103 struct secasvar
*, u_int8_t
*, u_int8_t
*);
104 static int esp_3des_blockencrypt(const struct esp_algorithm
*,
105 struct secasvar
*, u_int8_t
*, u_int8_t
*);
106 static int esp_common_ivlen(const struct esp_algorithm
*,
108 static int esp_cbc_decrypt(struct mbuf
*, size_t,
109 struct secasvar
*, const struct esp_algorithm
*, int);
110 static int esp_cbc_encrypt(struct mbuf
*, size_t, size_t,
111 struct secasvar
*, const struct esp_algorithm
*, int);
115 static const struct esp_algorithm esp_algorithms
[] = {
116 { 8, -1, esp_descbc_mature
, 64, 64, esp_des_schedlen
,
118 esp_descbc_ivlen
, esp_cbc_decrypt
,
119 esp_cbc_encrypt
, esp_des_schedule
,
120 esp_des_blockdecrypt
, esp_des_blockencrypt
, },
121 { 8, 8, esp_cbc_mature
, 192, 192, esp_3des_schedlen
,
123 esp_common_ivlen
, esp_cbc_decrypt
,
124 esp_cbc_encrypt
, esp_3des_schedule
,
125 esp_3des_blockdecrypt
, esp_3des_blockencrypt
, },
126 { 1, 0, esp_null_mature
, 0, 2048, NULL
,
128 esp_common_ivlen
, esp_null_decrypt
,
129 esp_null_encrypt
, NULL
,
131 { 8, 8, esp_cbc_mature
, 40, 448, esp_blowfish_schedlen
, "blowfish-cbc",
132 esp_common_ivlen
, esp_cbc_decrypt
,
133 esp_cbc_encrypt
, esp_blowfish_schedule
,
134 esp_blowfish_blockdecrypt
, esp_blowfish_blockencrypt
, },
135 { 8, 8, esp_cbc_mature
, 40, 128, esp_cast128_schedlen
,
137 esp_common_ivlen
, esp_cbc_decrypt
,
138 esp_cbc_encrypt
, esp_cast128_schedule
,
139 esp_cast128_blockdecrypt
, esp_cast128_blockencrypt
, },
140 { 16, 16, esp_cbc_mature
, 128, 256, esp_rijndael_schedlen
,
142 esp_common_ivlen
, esp_cbc_decrypt
,
143 esp_cbc_encrypt
, esp_rijndael_schedule
,
144 esp_rijndael_blockdecrypt
, esp_rijndael_blockencrypt
},
145 { 16, 8, esp_aesctr_mature
, 160, 288, esp_aesctr_schedlen
,
147 esp_common_ivlen
, esp_aesctr_decrypt
,
148 esp_aesctr_encrypt
, esp_aesctr_schedule
,
152 const struct esp_algorithm
*
153 esp_algorithm_lookup(int idx
)
157 case SADB_EALG_DESCBC
:
158 return &esp_algorithms
[0];
159 case SADB_EALG_3DESCBC
:
160 return &esp_algorithms
[1];
162 return &esp_algorithms
[2];
163 case SADB_X_EALG_BLOWFISHCBC
:
164 return &esp_algorithms
[3];
165 case SADB_X_EALG_CAST128CBC
:
166 return &esp_algorithms
[4];
167 case SADB_X_EALG_RIJNDAELCBC
:
168 return &esp_algorithms
[5];
169 case SADB_X_EALG_AESCTR
:
170 return &esp_algorithms
[6];
177 esp_max_padbound(void)
180 static int padbound
= 0;
185 for (idx
= 0; idx
< sizeof(esp_algorithms
)/sizeof(esp_algorithms
[0]);
187 if (esp_algorithms
[idx
].padbound
> padbound
)
188 padbound
= esp_algorithms
[idx
].padbound
;
197 static int ivlen
= 0;
202 for (idx
= 0; idx
< sizeof(esp_algorithms
)/sizeof(esp_algorithms
[0]);
204 if (esp_algorithms
[idx
].ivlenval
> ivlen
)
205 ivlen
= esp_algorithms
[idx
].ivlenval
;
211 esp_schedule(const struct esp_algorithm
*algo
, struct secasvar
*sav
)
215 /* check for key length */
216 if (_KEYBITS(sav
->key_enc
) < algo
->keymin
||
217 _KEYBITS(sav
->key_enc
) > algo
->keymax
) {
219 "esp_schedule %s: unsupported key length %d: "
220 "needs %d to %d bits\n", algo
->name
, _KEYBITS(sav
->key_enc
),
221 algo
->keymin
, algo
->keymax
));
225 /* already allocated */
226 if (sav
->sched
&& sav
->schedlen
!= 0)
228 /* no schedule necessary */
229 if (!algo
->schedule
|| !algo
->schedlen
)
232 sav
->schedlen
= (*algo
->schedlen
)(algo
);
233 sav
->sched
= malloc(sav
->schedlen
, M_SECA
, M_DONTWAIT
);
239 error
= (*algo
->schedule
)(algo
, sav
);
241 ipseclog((LOG_ERR
, "esp_schedule %s: error %d\n",
243 memset(sav
->sched
, 0, sav
->schedlen
);
244 free(sav
->sched
, M_SECA
);
252 esp_null_mature(struct secasvar
*sav
)
255 /* anything is okay */
262 size_t off
, /* offset to ESP header */
263 struct secasvar
*sav
,
264 const struct esp_algorithm
*algo
,
269 return 0; /* do nothing */
275 size_t off
, /* offset to ESP header */
276 size_t plen
, /* payload length (to be encrypted) */
277 struct secasvar
*sav
,
278 const struct esp_algorithm
*algo
,
283 return 0; /* do nothing */
287 esp_descbc_mature(struct secasvar
*sav
)
289 const struct esp_algorithm
*algo
;
291 if (!(sav
->flags
& SADB_X_EXT_OLD
) && (sav
->flags
& SADB_X_EXT_IV4B
)) {
292 ipseclog((LOG_ERR
, "esp_cbc_mature: "
293 "algorithm incompatible with 4 octets IV length\n"));
298 ipseclog((LOG_ERR
, "esp_descbc_mature: no key is given.\n"));
302 algo
= esp_algorithm_lookup(sav
->alg_enc
);
305 "esp_descbc_mature: unsupported algorithm.\n"));
309 if (_KEYBITS(sav
->key_enc
) < algo
->keymin
||
310 _KEYBITS(sav
->key_enc
) > algo
->keymax
) {
312 "esp_descbc_mature: invalid key length %d.\n",
313 _KEYBITS(sav
->key_enc
)));
318 if (des_is_weak_key((des_cblock
*)_KEYBUF(sav
->key_enc
))) {
320 "esp_descbc_mature: weak key was passed.\n"));
328 esp_descbc_ivlen(const struct esp_algorithm
*algo
,
329 struct secasvar
*sav
)
334 if ((sav
->flags
& SADB_X_EXT_OLD
) && (sav
->flags
& SADB_X_EXT_IV4B
))
336 if (!(sav
->flags
& SADB_X_EXT_OLD
) && (sav
->flags
& SADB_X_EXT_DERIV
))
342 esp_des_schedlen(const struct esp_algorithm
*algo
)
345 return sizeof(des_key_schedule
);
349 esp_des_schedule(const struct esp_algorithm
*algo
,
350 struct secasvar
*sav
)
353 if (des_key_sched((des_cblock
*)_KEYBUF(sav
->key_enc
),
354 *(des_key_schedule
*)sav
->sched
))
361 esp_des_blockdecrypt( const struct esp_algorithm
*algo
,
362 struct secasvar
*sav
, u_int8_t
*s
, u_int8_t
*d
)
365 /* assumption: d has a good alignment */
366 memcpy(d
, s
, sizeof(DES_LONG
) * 2);
367 des_ecb_encrypt((des_cblock
*)d
, (des_cblock
*)d
,
368 *(des_key_schedule
*)sav
->sched
, DES_DECRYPT
);
373 esp_des_blockencrypt(const struct esp_algorithm
*algo
,
374 struct secasvar
*sav
, u_int8_t
*s
, u_int8_t
*d
)
377 /* assumption: d has a good alignment */
378 memcpy(d
, s
, sizeof(DES_LONG
) * 2);
379 des_ecb_encrypt((des_cblock
*)d
, (des_cblock
*)d
,
380 *(des_key_schedule
*)sav
->sched
, DES_ENCRYPT
);
385 esp_cbc_mature(struct secasvar
*sav
)
388 const struct esp_algorithm
*algo
;
390 if (sav
->flags
& SADB_X_EXT_OLD
) {
392 "esp_cbc_mature: algorithm incompatible with esp-old\n"));
395 if (sav
->flags
& SADB_X_EXT_DERIV
) {
397 "esp_cbc_mature: algorithm incompatible with derived\n"));
402 ipseclog((LOG_ERR
, "esp_cbc_mature: no key is given.\n"));
406 algo
= esp_algorithm_lookup(sav
->alg_enc
);
409 "esp_cbc_mature %s: unsupported algorithm.\n", algo
->name
));
413 keylen
= sav
->key_enc
->sadb_key_bits
;
414 if (keylen
< algo
->keymin
|| algo
->keymax
< keylen
) {
416 "esp_cbc_mature %s: invalid key length %d.\n",
417 algo
->name
, sav
->key_enc
->sadb_key_bits
));
420 switch (sav
->alg_enc
) {
421 case SADB_EALG_3DESCBC
:
423 if (des_is_weak_key((des_cblock
*)_KEYBUF(sav
->key_enc
)) ||
424 des_is_weak_key((des_cblock
*)(_KEYBUF(sav
->key_enc
) + 8)) ||
425 des_is_weak_key((des_cblock
*)(_KEYBUF(sav
->key_enc
) + 16))) {
427 "esp_cbc_mature %s: weak key was passed.\n",
432 case SADB_X_EALG_BLOWFISHCBC
:
433 case SADB_X_EALG_CAST128CBC
:
435 case SADB_X_EALG_RIJNDAELCBC
:
436 /* allows specific key sizes only */
437 if (!(keylen
== 128 || keylen
== 192 || keylen
== 256)) {
439 "esp_cbc_mature %s: invalid key length %d.\n",
440 algo
->name
, keylen
));
450 esp_blowfish_schedlen(const struct esp_algorithm
*algo
)
453 return sizeof(BF_KEY
);
457 esp_blowfish_schedule(const struct esp_algorithm
*algo
,
458 struct secasvar
*sav
)
461 BF_set_key((BF_KEY
*)sav
->sched
, _KEYLEN(sav
->key_enc
),
462 _KEYBUF(sav
->key_enc
));
467 esp_blowfish_blockdecrypt(const struct esp_algorithm
*algo
,
468 struct secasvar
*sav
, u_int8_t
*s
, u_int8_t
*d
)
471 BF_ecb_encrypt(s
, d
, (BF_KEY
*)sav
->sched
, 0);
476 esp_blowfish_blockencrypt(const struct esp_algorithm
*algo
,
477 struct secasvar
*sav
, u_int8_t
*s
, u_int8_t
*d
)
480 BF_ecb_encrypt(s
, d
, (BF_KEY
*)sav
->sched
, 1);
485 esp_cast128_schedlen(const struct esp_algorithm
*algo
)
488 return sizeof(cast128_key
);
492 esp_cast128_schedule(const struct esp_algorithm
*algo
,
493 struct secasvar
*sav
)
496 cast128_setkey((cast128_key
*)sav
->sched
, _KEYBUF(sav
->key_enc
),
497 _KEYLEN(sav
->key_enc
));
502 esp_cast128_blockdecrypt(const struct esp_algorithm
*algo
,
503 struct secasvar
*sav
, u_int8_t
*s
, u_int8_t
*d
)
506 cast128_decrypt((cast128_key
*)sav
->sched
, s
, d
);
511 esp_cast128_blockencrypt(const struct esp_algorithm
*algo
,
512 struct secasvar
*sav
, u_int8_t
*s
, u_int8_t
*d
)
515 cast128_encrypt((cast128_key
*)sav
->sched
, s
, d
);
520 esp_3des_schedlen(const struct esp_algorithm
*algo
)
523 return sizeof(des_key_schedule
) * 3;
527 esp_3des_schedule(const struct esp_algorithm
*algo
,
528 struct secasvar
*sav
)
535 p
= (des_key_schedule
*)sav
->sched
;
536 k
= _KEYBUF(sav
->key_enc
);
537 for (i
= 0; i
< 3; i
++) {
538 error
= des_key_sched((des_cblock
*)(k
+ 8 * i
), p
[i
]);
546 esp_3des_blockdecrypt(const struct esp_algorithm
*algo
,
547 struct secasvar
*sav
, u_int8_t
*s
, u_int8_t
*d
)
551 /* assumption: d has a good alignment */
552 p
= (des_key_schedule
*)sav
->sched
;
553 memcpy(d
, s
, sizeof(DES_LONG
) * 2);
554 des_ecb3_encrypt((des_cblock
*)d
, (des_cblock
*)d
,
555 p
[0], p
[1], p
[2], DES_DECRYPT
);
560 esp_3des_blockencrypt(const struct esp_algorithm
*algo
,
561 struct secasvar
*sav
, u_int8_t
*s
, u_int8_t
*d
)
565 /* assumption: d has a good alignment */
566 p
= (des_key_schedule
*)sav
->sched
;
567 memcpy(d
, s
, sizeof(DES_LONG
) * 2);
568 des_ecb3_encrypt((des_cblock
*)d
, (des_cblock
*)d
,
569 p
[0], p
[1], p
[2], DES_ENCRYPT
);
574 esp_common_ivlen(const struct esp_algorithm
*algo
,
575 struct secasvar
*sav
)
579 panic("esp_common_ivlen: unknown algorithm");
580 return algo
->ivlenval
;
584 esp_cbc_decrypt(struct mbuf
*m
, size_t off
, struct secasvar
*sav
,
585 const struct esp_algorithm
*algo
, int ivlen
)
588 struct mbuf
*d
, *d0
, *dp
;
589 int soff
, doff
; /* offset from the head of chain, to head of this mbuf */
590 int sn
, dn
; /* offset from the head of the mbuf, to meat */
591 size_t ivoff
, bodyoff
;
592 u_int8_t iv
[MAXIVLEN
], *ivp
;
593 u_int8_t sbuf
[MAXIVLEN
], *sp
;
600 if (ivlen
!= sav
->ivlen
|| ivlen
> sizeof(iv
)) {
601 ipseclog((LOG_ERR
, "esp_cbc_decrypt %s: "
602 "unsupported ivlen %d\n", algo
->name
, ivlen
));
607 /* assumes blocklen == padbound */
608 blocklen
= algo
->padbound
;
611 if (blocklen
> sizeof(iv
)) {
612 ipseclog((LOG_ERR
, "esp_cbc_decrypt %s: "
613 "unsupported blocklen %d\n", algo
->name
, blocklen
));
619 if (sav
->flags
& SADB_X_EXT_OLD
) {
621 ivoff
= off
+ sizeof(struct esp
);
622 bodyoff
= off
+ sizeof(struct esp
) + ivlen
;
625 if (sav
->flags
& SADB_X_EXT_DERIV
) {
627 * draft-ietf-ipsec-ciph-des-derived-00.txt
628 * uses sequence number field as IV field.
630 ivoff
= off
+ sizeof(struct esp
);
631 bodyoff
= off
+ sizeof(struct esp
) + sizeof(u_int32_t
);
632 ivlen
= sizeof(u_int32_t
);
634 ivoff
= off
+ sizeof(struct newesp
);
635 bodyoff
= off
+ sizeof(struct newesp
) + ivlen
;
640 m_copydata(m
, ivoff
, ivlen
, (void *)iv
);
643 if (ivlen
== blocklen
)
645 else if (ivlen
== 4 && blocklen
== 8) {
646 memcpy(&iv
[4], &iv
[0], 4);
652 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: "
653 "unsupported ivlen/blocklen: %d %d\n",
654 algo
->name
, ivlen
, blocklen
));
659 if (m
->m_pkthdr
.len
< bodyoff
) {
660 ipseclog((LOG_ERR
, "esp_cbc_decrypt %s: bad len %d/%lu\n",
661 algo
->name
, m
->m_pkthdr
.len
, (unsigned long)bodyoff
));
665 if ((m
->m_pkthdr
.len
- bodyoff
) % blocklen
) {
666 ipseclog((LOG_ERR
, "esp_cbc_decrypt %s: "
667 "payload length must be multiple of %d\n",
668 algo
->name
, blocklen
));
675 soff
= doff
= sn
= dn
= 0;
679 while (soff
< bodyoff
) {
680 if (soff
+ s
->m_len
> bodyoff
) {
691 /* skip over empty mbuf */
692 while (s
&& s
->m_len
== 0)
695 while (soff
< m
->m_pkthdr
.len
) {
697 if (sn
+ blocklen
<= s
->m_len
) {
698 /* body is continuous */
699 sp
= mtod(s
, u_int8_t
*) + sn
;
701 /* body is non-continuous */
702 m_copydata(s
, sn
, blocklen
, (void *)sbuf
);
707 if (!d
|| dn
+ blocklen
> d
->m_len
) {
710 MGET(d
, M_DONTWAIT
, MT_DATA
);
711 i
= m
->m_pkthdr
.len
- (soff
+ sn
);
713 MCLGET(d
, M_DONTWAIT
);
714 if ((d
->m_flags
& M_EXT
) == 0) {
730 d
->m_len
= (M_TRAILINGSPACE(d
) / blocklen
) * blocklen
;
737 (*algo
->blockdecrypt
)(algo
, sav
, sp
, mtod(d
, u_int8_t
*) + dn
);
741 q
= mtod(d
, u_int8_t
*) + dn
;
742 for (i
= 0; i
< blocklen
; i
++)
747 memcpy(iv
, sbuf
, blocklen
);
755 /* find the next source block */
756 while (s
&& sn
>= s
->m_len
) {
762 /* skip over empty mbuf */
763 while (s
&& s
->m_len
== 0)
767 m_freem(scut
->m_next
);
768 scut
->m_len
= scutoff
;
772 memset(iv
, 0, sizeof(iv
));
773 memset(sbuf
, 0, sizeof(sbuf
));
783 struct secasvar
*sav
,
784 const struct esp_algorithm
*algo
,
789 struct mbuf
*d
, *d0
, *dp
;
790 int soff
, doff
; /* offset from the head of chain, to head of this mbuf */
791 int sn
, dn
; /* offset from the head of the mbuf, to meat */
792 size_t ivoff
, bodyoff
;
793 u_int8_t iv
[MAXIVLEN
], *ivp
;
794 u_int8_t sbuf
[MAXIVLEN
], *sp
;
802 if (ivlen
!= sav
->ivlen
|| ivlen
> sizeof(iv
)) {
803 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: "
804 "unsupported ivlen %d\n", algo
->name
, ivlen
));
809 /* assumes blocklen == padbound */
810 blocklen
= algo
->padbound
;
813 if (blocklen
> sizeof(iv
)) {
814 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: "
815 "unsupported blocklen %d\n", algo
->name
, blocklen
));
821 if (sav
->flags
& SADB_X_EXT_OLD
) {
823 ivoff
= off
+ sizeof(struct esp
);
824 bodyoff
= off
+ sizeof(struct esp
) + ivlen
;
828 if (sav
->flags
& SADB_X_EXT_DERIV
) {
830 * draft-ietf-ipsec-ciph-des-derived-00.txt
831 * uses sequence number field as IV field.
833 ivoff
= off
+ sizeof(struct esp
);
834 bodyoff
= off
+ sizeof(struct esp
) + sizeof(u_int32_t
);
835 ivlen
= sizeof(u_int32_t
);
838 ivoff
= off
+ sizeof(struct newesp
);
839 bodyoff
= off
+ sizeof(struct newesp
) + ivlen
;
844 /* put iv into the packet. if we are in derived mode, use seqno. */
846 m_copydata(m
, ivoff
, ivlen
, (void *)iv
);
848 memcpy(iv
, sav
->iv
, ivlen
);
849 /* maybe it is better to overwrite dest, not source */
850 m_copyback(m
, ivoff
, ivlen
, (void *)iv
);
854 if (ivlen
== blocklen
)
856 else if (ivlen
== 4 && blocklen
== 8) {
857 memcpy(&iv
[4], &iv
[0], 4);
863 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: "
864 "unsupported ivlen/blocklen: %d %d\n",
865 algo
->name
, ivlen
, blocklen
));
870 if (m
->m_pkthdr
.len
< bodyoff
) {
871 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: bad len %d/%lu\n",
872 algo
->name
, m
->m_pkthdr
.len
, (unsigned long)bodyoff
));
876 if ((m
->m_pkthdr
.len
- bodyoff
) % blocklen
) {
877 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: "
878 "payload length must be multiple of %lu\n",
879 algo
->name
, (unsigned long)algo
->padbound
));
886 soff
= doff
= sn
= dn
= 0;
890 while (soff
< bodyoff
) {
891 if (soff
+ s
->m_len
> bodyoff
) {
902 /* skip over empty mbuf */
903 while (s
&& s
->m_len
== 0)
906 while (soff
< m
->m_pkthdr
.len
) {
908 if (sn
+ blocklen
<= s
->m_len
) {
909 /* body is continuous */
910 sp
= mtod(s
, u_int8_t
*) + sn
;
912 /* body is non-continuous */
913 m_copydata(s
, sn
, blocklen
, (void *)sbuf
);
918 if (!d
|| dn
+ blocklen
> d
->m_len
) {
921 MGET(d
, M_DONTWAIT
, MT_DATA
);
922 i
= m
->m_pkthdr
.len
- (soff
+ sn
);
924 MCLGET(d
, M_DONTWAIT
);
925 if ((d
->m_flags
& M_EXT
) == 0) {
941 d
->m_len
= (M_TRAILINGSPACE(d
) / blocklen
) * blocklen
;
950 for (i
= 0; i
< blocklen
; i
++)
954 (*algo
->blockencrypt
)(algo
, sav
, sp
, mtod(d
, u_int8_t
*) + dn
);
957 ivp
= mtod(d
, u_int8_t
*) + dn
;
962 /* find the next source block */
963 while (s
&& sn
>= s
->m_len
) {
969 /* skip over empty mbuf */
970 while (s
&& s
->m_len
== 0)
974 m_freem(scut
->m_next
);
975 scut
->m_len
= scutoff
;
979 memset(iv
, 0, sizeof(iv
));
980 memset(sbuf
, 0, sizeof(sbuf
));
987 /*------------------------------------------------------------*/
989 /* does not free m0 on error
991 * skip - offset to ESP header
992 * length - payloadd length
995 esp_auth(struct mbuf
*m0
, size_t skip
, size_t length
,
996 struct secasvar
*sav
, u_char
*sum
)
1000 struct ah_algorithm_state s
;
1001 u_char sumbuf
[AH_MAXSUMSIZE
];
1002 const struct ah_algorithm
*algo
;
1007 if (m0
->m_pkthdr
.len
< skip
) {
1008 ipseclog((LOG_DEBUG
, "esp_auth: mbuf length < skip\n"));
1011 if (m0
->m_pkthdr
.len
< skip
+ length
) {
1012 ipseclog((LOG_DEBUG
,
1013 "esp_auth: mbuf length < skip + length\n"));
1017 * length of esp part (excluding authentication data) must be 4n,
1018 * since nexthdr must be at offset 4n+3.
1021 ipseclog((LOG_ERR
, "esp_auth: length is not multiple of 4\n"));
1025 ipseclog((LOG_DEBUG
, "esp_auth: NULL SA passed\n"));
1028 algo
= ah_algorithm_lookup(sav
->alg_auth
);
1031 "esp_auth: bad ESP auth algorithm passed: %d\n",
1039 siz
= (((*algo
->sumsiz
)(sav
) + 3) & ~(4 - 1));
1040 if (sizeof(sumbuf
) < siz
) {
1041 ipseclog((LOG_DEBUG
,
1042 "esp_auth: AH_MAXSUMSIZE is too small: siz=%lu\n",
1047 /* skip the header */
1050 panic("mbuf chain?");
1051 if (m
->m_len
<= skip
) {
1061 error
= (*algo
->init
)(&s
, sav
);
1065 while (0 < length
) {
1067 panic("mbuf chain?");
1069 if (m
->m_len
- off
< length
) {
1070 (*algo
->update
)(&s
, mtod(m
, u_char
*) + off
,
1072 length
-= m
->m_len
- off
;
1076 (*algo
->update
)(&s
, mtod(m
, u_char
*) + off
, length
);
1080 (*algo
->result
)(&s
, sumbuf
, sizeof(sumbuf
));
1081 memcpy(sum
, sumbuf
, siz
); /* XXX */