1 /* $FreeBSD: src/sys/netinet6/esp_core.c,v 1.1.2.4 2002/03/26 10:12:29 ume Exp $ */
2 /* $KAME: esp_core.c,v 1.50 2000/11/02 12:27:38 itojun 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
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/malloc.h>
39 #include <sys/domain.h>
40 #include <sys/protosw.h>
41 #include <sys/socket.h>
42 #include <sys/errno.h>
44 #include <sys/kernel.h>
45 #include <sys/syslog.h>
47 #include <kern/locks.h>
50 #include <net/route.h>
52 #include <netinet/in.h>
53 #include <netinet/in_var.h>
55 #include <netinet/ip6.h>
56 #include <netinet6/ip6_var.h>
57 #include <netinet/icmp6.h>
60 #include <netinet6/ipsec.h>
62 #include <netinet6/ipsec6.h>
64 #include <netinet6/ah.h>
66 #include <netinet6/ah6.h>
68 #include <netinet6/esp.h>
70 #include <netinet6/esp6.h>
72 #include <netinet6/esp_rijndael.h>
73 #include <net/pfkeyv2.h>
74 #include <netkey/keydb.h>
75 #include <netkey/key.h>
76 #include <crypto/des/des.h>
77 #include <crypto/blowfish/blowfish.h>
78 #include <crypto/cast128/cast128.h>
80 #include <net/net_osdep.h>
82 #include <sys/kdebug.h>
83 #define DBG_LAYER_BEG NETDBG_CODE(DBG_NETIPSEC, 1)
84 #define DBG_LAYER_END NETDBG_CODE(DBG_NETIPSEC, 3)
85 #define DBG_FNC_ESPAUTH NETDBG_CODE(DBG_NETIPSEC, (8 << 8))
87 extern lck_mtx_t
*sadb_mutex
;
89 static int esp_null_mature(struct secasvar
*);
90 static int esp_null_decrypt(struct mbuf
*, size_t,
91 struct secasvar
*, const struct esp_algorithm
*, int);
92 static int esp_null_encrypt(struct mbuf
*, size_t, size_t,
93 struct secasvar
*, const struct esp_algorithm
*, int);
94 static int esp_descbc_mature(struct secasvar
*);
95 static int esp_descbc_ivlen(const struct esp_algorithm
*,
97 static int esp_des_schedule(const struct esp_algorithm
*,
99 static int esp_des_schedlen(const struct esp_algorithm
*);
100 static int esp_des_blockdecrypt(const struct esp_algorithm
*,
101 struct secasvar
*, u_int8_t
*, u_int8_t
*);
102 static int esp_des_blockencrypt(const struct esp_algorithm
*,
103 struct secasvar
*, u_int8_t
*, u_int8_t
*);
104 static int esp_cbc_mature(struct secasvar
*);
105 static int esp_blowfish_schedule(const struct esp_algorithm
*,
107 static int esp_blowfish_schedlen(const struct esp_algorithm
*);
108 static int esp_blowfish_blockdecrypt(const struct esp_algorithm
*,
109 struct secasvar
*, u_int8_t
*, u_int8_t
*);
110 static int esp_blowfish_blockencrypt(const struct esp_algorithm
*,
111 struct secasvar
*, u_int8_t
*, u_int8_t
*);
112 static int esp_cast128_schedule(const struct esp_algorithm
*,
114 static int esp_cast128_schedlen(const struct esp_algorithm
*);
115 static int esp_cast128_blockdecrypt(const struct esp_algorithm
*,
116 struct secasvar
*, u_int8_t
*, u_int8_t
*);
117 static int esp_cast128_blockencrypt(const struct esp_algorithm
*,
118 struct secasvar
*, u_int8_t
*, u_int8_t
*);
119 static int esp_3des_schedule(const struct esp_algorithm
*,
121 static int esp_3des_schedlen(const struct esp_algorithm
*);
122 static int esp_3des_blockdecrypt(const struct esp_algorithm
*,
123 struct secasvar
*, u_int8_t
*, u_int8_t
*);
124 static int esp_3des_blockencrypt(const struct esp_algorithm
*,
125 struct secasvar
*, u_int8_t
*, u_int8_t
*);
126 static int esp_common_ivlen(const struct esp_algorithm
*,
128 static int esp_cbc_decrypt(struct mbuf
*, size_t,
129 struct secasvar
*, const struct esp_algorithm
*, int);
130 static int esp_cbc_encrypt(struct mbuf
*, size_t, size_t,
131 struct secasvar
*, const struct esp_algorithm
*, int);
135 static const struct esp_algorithm esp_algorithms
[] = {
136 { 8, -1, esp_descbc_mature
, 64, 64, esp_des_schedlen
,
138 esp_descbc_ivlen
, esp_cbc_decrypt
,
139 esp_cbc_encrypt
, esp_des_schedule
,
140 esp_des_blockdecrypt
, esp_des_blockencrypt
, },
141 { 8, 8, esp_cbc_mature
, 192, 192, esp_3des_schedlen
,
143 esp_common_ivlen
, esp_cbc_decrypt
,
144 esp_cbc_encrypt
, esp_3des_schedule
,
145 esp_3des_blockdecrypt
, esp_3des_blockencrypt
, },
146 { 1, 0, esp_null_mature
, 0, 2048, 0, "null",
147 esp_common_ivlen
, esp_null_decrypt
,
148 esp_null_encrypt
, NULL
, },
149 { 8, 8, esp_cbc_mature
, 40, 448, esp_blowfish_schedlen
, "blowfish-cbc",
150 esp_common_ivlen
, esp_cbc_decrypt
,
151 esp_cbc_encrypt
, esp_blowfish_schedule
,
152 esp_blowfish_blockdecrypt
, esp_blowfish_blockencrypt
, },
153 { 8, 8, esp_cbc_mature
, 40, 128, esp_cast128_schedlen
,
155 esp_common_ivlen
, esp_cbc_decrypt
,
156 esp_cbc_encrypt
, esp_cast128_schedule
,
157 esp_cast128_blockdecrypt
, esp_cast128_blockencrypt
, },
158 { 16, 16, esp_cbc_mature
, 128, 256, esp_aes_schedlen
,
160 esp_common_ivlen
, esp_cbc_decrypt_aes
,
161 esp_cbc_encrypt_aes
, esp_aes_schedule
,
165 const struct esp_algorithm
*
166 esp_algorithm_lookup(idx
)
171 case SADB_EALG_DESCBC
:
172 return &esp_algorithms
[0];
173 case SADB_EALG_3DESCBC
:
174 return &esp_algorithms
[1];
176 return &esp_algorithms
[2];
177 case SADB_X_EALG_BLOWFISHCBC
:
178 return &esp_algorithms
[3];
179 case SADB_X_EALG_CAST128CBC
:
180 return &esp_algorithms
[4];
181 case SADB_X_EALG_RIJNDAELCBC
:
182 return &esp_algorithms
[5];
195 for (idx
= 0; idx
< sizeof(esp_algorithms
)/sizeof(esp_algorithms
[0]);
197 if (esp_algorithms
[idx
].ivlenval
> ivlen
)
198 ivlen
= esp_algorithms
[idx
].ivlenval
;
205 esp_schedule(algo
, sav
)
206 const struct esp_algorithm
*algo
;
207 struct secasvar
*sav
;
211 /* check for key length */
212 if (_KEYBITS(sav
->key_enc
) < algo
->keymin
||
213 _KEYBITS(sav
->key_enc
) > algo
->keymax
) {
215 "esp_schedule %s: unsupported key length %d: "
216 "needs %d to %d bits\n", algo
->name
, _KEYBITS(sav
->key_enc
),
217 algo
->keymin
, algo
->keymax
));
221 /* already allocated */
222 if (sav
->sched
&& sav
->schedlen
!= 0)
224 /* no schedule necessary */
225 if (!algo
->schedule
|| !algo
->schedlen
)
228 sav
->schedlen
= (*algo
->schedlen
)(algo
);
229 if (sav
->schedlen
< 0)
232 //#### that malloc should be replaced by a saved buffer...
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 bzero(sav
->sched
, sav
->schedlen
);
244 FREE(sav
->sched
, M_SECA
);
253 struct secasvar
*sav
;
256 /* anything is okay */
261 esp_null_decrypt(m
, off
, sav
, algo
, ivlen
)
263 size_t off
; /* offset to ESP header */
264 struct secasvar
*sav
;
265 const struct esp_algorithm
*algo
;
269 return 0; /* do nothing */
273 esp_null_encrypt(m
, off
, plen
, sav
, algo
, ivlen
)
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
;
282 return 0; /* do nothing */
286 esp_descbc_mature(sav
)
287 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(algo
, sav
)
329 const struct esp_algorithm
*algo
;
330 struct secasvar
*sav
;
335 if ((sav
->flags
& SADB_X_EXT_OLD
) && (sav
->flags
& SADB_X_EXT_IV4B
))
337 if (!(sav
->flags
& SADB_X_EXT_OLD
) && (sav
->flags
& SADB_X_EXT_DERIV
))
343 esp_des_schedlen(algo
)
344 const struct esp_algorithm
*algo
;
347 return sizeof(des_key_schedule
);
351 esp_des_schedule(algo
, sav
)
352 const struct esp_algorithm
*algo
;
353 struct secasvar
*sav
;
356 if (des_key_sched((des_cblock
*)_KEYBUF(sav
->key_enc
),
357 *(des_key_schedule
*)sav
->sched
))
364 esp_des_blockdecrypt(algo
, sav
, s
, d
)
365 const struct esp_algorithm
*algo
;
366 struct secasvar
*sav
;
371 /* assumption: d has a good alignment */
372 bcopy(s
, d
, sizeof(DES_LONG
) * 2);
373 des_ecb_encrypt((des_cblock
*)d
, (des_cblock
*)d
,
374 *(des_key_schedule
*)sav
->sched
, DES_DECRYPT
);
379 esp_des_blockencrypt(algo
, sav
, s
, d
)
380 const struct esp_algorithm
*algo
;
381 struct secasvar
*sav
;
386 /* assumption: d has a good alignment */
387 bcopy(s
, d
, sizeof(DES_LONG
) * 2);
388 des_ecb_encrypt((des_cblock
*)d
, (des_cblock
*)d
,
389 *(des_key_schedule
*)sav
->sched
, DES_ENCRYPT
);
395 struct secasvar
*sav
;
398 const struct esp_algorithm
*algo
;
400 if (sav
->flags
& SADB_X_EXT_OLD
) {
402 "esp_cbc_mature: algorithm incompatible with esp-old\n"));
405 if (sav
->flags
& SADB_X_EXT_DERIV
) {
407 "esp_cbc_mature: algorithm incompatible with derived\n"));
412 ipseclog((LOG_ERR
, "esp_cbc_mature: no key is given.\n"));
416 algo
= esp_algorithm_lookup(sav
->alg_enc
);
419 "esp_cbc_mature %s: unsupported algorithm.\n", algo
->name
));
423 keylen
= sav
->key_enc
->sadb_key_bits
;
424 if (keylen
< algo
->keymin
|| algo
->keymax
< keylen
) {
426 "esp_cbc_mature %s: invalid key length %d.\n",
427 algo
->name
, sav
->key_enc
->sadb_key_bits
));
430 switch (sav
->alg_enc
) {
431 case SADB_EALG_3DESCBC
:
433 if (des_is_weak_key((des_cblock
*)_KEYBUF(sav
->key_enc
)) ||
434 des_is_weak_key((des_cblock
*)(_KEYBUF(sav
->key_enc
) + 8)) ||
435 des_is_weak_key((des_cblock
*)(_KEYBUF(sav
->key_enc
) + 16))) {
437 "esp_cbc_mature %s: weak key was passed.\n",
442 case SADB_X_EALG_BLOWFISHCBC
:
443 case SADB_X_EALG_CAST128CBC
:
445 case SADB_X_EALG_RIJNDAELCBC
:
446 /* allows specific key sizes only */
447 if (!(keylen
== 128 || keylen
== 192 || keylen
== 256)) {
449 "esp_cbc_mature %s: invalid key length %d.\n",
450 algo
->name
, keylen
));
460 esp_blowfish_schedlen(algo
)
461 const struct esp_algorithm
*algo
;
464 return sizeof(BF_KEY
);
468 esp_blowfish_schedule(algo
, sav
)
469 const struct esp_algorithm
*algo
;
470 struct secasvar
*sav
;
473 BF_set_key((BF_KEY
*)sav
->sched
, _KEYLEN(sav
->key_enc
),
474 _KEYBUF(sav
->key_enc
));
479 esp_blowfish_blockdecrypt(algo
, sav
, s
, d
)
480 const struct esp_algorithm
*algo
;
481 struct secasvar
*sav
;
485 /* HOLY COW! BF_decrypt() takes values in host byteorder */
488 bcopy(s
, t
, sizeof(t
));
491 BF_decrypt(t
, (BF_KEY
*)sav
->sched
);
494 bcopy(t
, d
, sizeof(t
));
499 esp_blowfish_blockencrypt(algo
, sav
, s
, d
)
500 const struct esp_algorithm
*algo
;
501 struct secasvar
*sav
;
505 /* HOLY COW! BF_encrypt() takes values in host byteorder */
508 bcopy(s
, t
, sizeof(t
));
511 BF_encrypt(t
, (BF_KEY
*)sav
->sched
);
514 bcopy(t
, d
, sizeof(t
));
519 esp_cast128_schedlen(algo
)
520 const struct esp_algorithm
*algo
;
523 return sizeof(u_int32_t
) * 32;
527 esp_cast128_schedule(algo
, sav
)
528 const struct esp_algorithm
*algo
;
529 struct secasvar
*sav
;
532 set_cast128_subkey((u_int32_t
*)sav
->sched
, _KEYBUF(sav
->key_enc
),
533 _KEYLEN(sav
->key_enc
));
538 esp_cast128_blockdecrypt(algo
, sav
, s
, d
)
539 const struct esp_algorithm
*algo
;
540 struct secasvar
*sav
;
545 if (_KEYLEN(sav
->key_enc
) <= 80 / 8)
546 cast128_decrypt_round12(d
, s
, (u_int32_t
*)sav
->sched
);
548 cast128_decrypt_round16(d
, s
, (u_int32_t
*)sav
->sched
);
553 esp_cast128_blockencrypt(algo
, sav
, s
, d
)
554 const struct esp_algorithm
*algo
;
555 struct secasvar
*sav
;
560 if (_KEYLEN(sav
->key_enc
) <= 80 / 8)
561 cast128_encrypt_round12(d
, s
, (u_int32_t
*)sav
->sched
);
563 cast128_encrypt_round16(d
, s
, (u_int32_t
*)sav
->sched
);
568 esp_3des_schedlen(algo
)
569 const struct esp_algorithm
*algo
;
572 return sizeof(des_key_schedule
) * 3;
576 esp_3des_schedule(algo
, sav
)
577 const struct esp_algorithm
*algo
;
578 struct secasvar
*sav
;
585 p
= (des_key_schedule
*)sav
->sched
;
586 k
= _KEYBUF(sav
->key_enc
);
587 for (i
= 0; i
< 3; i
++) {
588 error
= des_key_sched((des_cblock
*)(k
+ 8 * i
), p
[i
]);
596 esp_3des_blockdecrypt(algo
, sav
, s
, d
)
597 const struct esp_algorithm
*algo
;
598 struct secasvar
*sav
;
604 /* assumption: d has a good alignment */
605 p
= (des_key_schedule
*)sav
->sched
;
606 bcopy(s
, d
, sizeof(DES_LONG
) * 2);
607 des_ecb3_encrypt((des_cblock
*)d
, (des_cblock
*)d
,
608 p
[0], p
[1], p
[2], DES_DECRYPT
);
613 esp_3des_blockencrypt(algo
, sav
, s
, d
)
614 const struct esp_algorithm
*algo
;
615 struct secasvar
*sav
;
621 /* assumption: d has a good alignment */
622 p
= (des_key_schedule
*)sav
->sched
;
623 bcopy(s
, d
, sizeof(DES_LONG
) * 2);
624 des_ecb3_encrypt((des_cblock
*)d
, (des_cblock
*)d
,
625 p
[0], p
[1], p
[2], DES_ENCRYPT
);
630 esp_common_ivlen(algo
, sav
)
631 const struct esp_algorithm
*algo
;
632 struct secasvar
*sav
;
636 panic("esp_common_ivlen: unknown algorithm");
637 return algo
->ivlenval
;
641 esp_cbc_decrypt(m
, off
, sav
, algo
, ivlen
)
644 struct secasvar
*sav
;
645 const struct esp_algorithm
*algo
;
649 struct mbuf
*d
, *d0
, *dp
;
650 int soff
, doff
; /* offset from the head of chain, to head of this mbuf */
651 int sn
, dn
; /* offset from the head of the mbuf, to meat */
652 size_t ivoff
, bodyoff
;
653 u_int8_t iv
[MAXIVLEN
], *ivp
;
654 u_int8_t sbuf
[MAXIVLEN
], *sp
;
662 if (ivlen
!= sav
->ivlen
|| ivlen
> sizeof(iv
)) {
663 ipseclog((LOG_ERR
, "esp_cbc_decrypt %s: "
664 "unsupported ivlen %d\n", algo
->name
, ivlen
));
669 /* assumes blocklen == padbound */
670 blocklen
= algo
->padbound
;
673 if (blocklen
> sizeof(iv
)) {
674 ipseclog((LOG_ERR
, "esp_cbc_decrypt %s: "
675 "unsupported blocklen %d\n", algo
->name
, blocklen
));
681 if (sav
->flags
& SADB_X_EXT_OLD
) {
683 ivoff
= off
+ sizeof(struct esp
);
684 bodyoff
= off
+ sizeof(struct esp
) + ivlen
;
688 if (sav
->flags
& SADB_X_EXT_DERIV
) {
690 * draft-ietf-ipsec-ciph-des-derived-00.txt
691 * uses sequence number field as IV field.
693 ivoff
= off
+ sizeof(struct esp
);
694 bodyoff
= off
+ sizeof(struct esp
) + sizeof(u_int32_t
);
695 ivlen
= sizeof(u_int32_t
);
698 ivoff
= off
+ sizeof(struct newesp
);
699 bodyoff
= off
+ sizeof(struct newesp
) + ivlen
;
705 m_copydata(m
, ivoff
, ivlen
, iv
);
708 if (ivlen
== blocklen
)
710 else if (ivlen
== 4 && blocklen
== 8) {
711 bcopy(&iv
[0], &iv
[4], 4);
717 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: "
718 "unsupported ivlen/blocklen: %d %d\n",
719 algo
->name
, ivlen
, blocklen
));
724 if (m
->m_pkthdr
.len
< bodyoff
) {
725 ipseclog((LOG_ERR
, "esp_cbc_decrypt %s: bad len %d/%lu\n",
726 algo
->name
, m
->m_pkthdr
.len
, (unsigned long)bodyoff
));
730 if ((m
->m_pkthdr
.len
- bodyoff
) % blocklen
) {
731 ipseclog((LOG_ERR
, "esp_cbc_decrypt %s: "
732 "payload length must be multiple of %d\n",
733 algo
->name
, blocklen
));
740 soff
= doff
= sn
= dn
= 0;
744 while (soff
< bodyoff
) {
745 if (soff
+ s
->m_len
> bodyoff
) {
756 /* skip over empty mbuf */
757 while (s
&& s
->m_len
== 0)
760 while (soff
< m
->m_pkthdr
.len
) {
762 if (sn
+ blocklen
<= s
->m_len
) {
763 /* body is continuous */
764 sp
= mtod(s
, u_int8_t
*) + sn
;
766 /* body is non-continuous */
767 m_copydata(s
, sn
, blocklen
, sbuf
);
772 if (!d
|| dn
+ blocklen
> d
->m_len
) {
775 MGET(d
, M_DONTWAIT
, MT_DATA
);
776 i
= m
->m_pkthdr
.len
- (soff
+ sn
);
778 MCLGET(d
, M_DONTWAIT
);
779 if ((d
->m_flags
& M_EXT
) == 0) {
795 d
->m_len
= (M_TRAILINGSPACE(d
) / blocklen
) * blocklen
;
802 (*algo
->blockdecrypt
)(algo
, sav
, sp
, mtod(d
, u_int8_t
*) + dn
);
806 q
= mtod(d
, u_int8_t
*) + dn
;
807 for (i
= 0; i
< blocklen
; i
++)
812 bcopy(sbuf
, iv
, blocklen
);
820 /* find the next source block */
821 while (s
&& sn
>= s
->m_len
) {
828 m_freem(scut
->m_next
);
829 scut
->m_len
= scutoff
;
833 bzero(iv
, sizeof(iv
));
834 bzero(sbuf
, sizeof(sbuf
));
840 esp_cbc_encrypt(m
, off
, plen
, sav
, algo
, ivlen
)
844 struct secasvar
*sav
;
845 const struct esp_algorithm
*algo
;
849 struct mbuf
*d
, *d0
, *dp
;
850 int soff
, doff
; /* offset from the head of chain, to head of this mbuf */
851 int sn
, dn
; /* offset from the head of the mbuf, to meat */
852 size_t ivoff
, bodyoff
;
853 u_int8_t iv
[MAXIVLEN
], *ivp
;
854 u_int8_t sbuf
[MAXIVLEN
], *sp
;
862 if (ivlen
!= sav
->ivlen
|| ivlen
> sizeof(iv
)) {
863 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: "
864 "unsupported ivlen %d\n", algo
->name
, ivlen
));
869 /* assumes blocklen == padbound */
870 blocklen
= algo
->padbound
;
873 if (blocklen
> sizeof(iv
)) {
874 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: "
875 "unsupported blocklen %d\n", algo
->name
, blocklen
));
881 if (sav
->flags
& SADB_X_EXT_OLD
) {
883 ivoff
= off
+ sizeof(struct esp
);
884 bodyoff
= off
+ sizeof(struct esp
) + ivlen
;
888 if (sav
->flags
& SADB_X_EXT_DERIV
) {
890 * draft-ietf-ipsec-ciph-des-derived-00.txt
891 * uses sequence number field as IV field.
893 ivoff
= off
+ sizeof(struct esp
);
894 bodyoff
= off
+ sizeof(struct esp
) + sizeof(u_int32_t
);
895 ivlen
= sizeof(u_int32_t
);
898 ivoff
= off
+ sizeof(struct newesp
);
899 bodyoff
= off
+ sizeof(struct newesp
) + ivlen
;
904 /* put iv into the packet. if we are in derived mode, use seqno. */
906 m_copydata(m
, ivoff
, ivlen
, iv
);
908 bcopy(sav
->iv
, iv
, ivlen
);
909 /* maybe it is better to overwrite dest, not source */
910 m_copyback(m
, ivoff
, ivlen
, iv
);
914 if (ivlen
== blocklen
)
916 else if (ivlen
== 4 && blocklen
== 8) {
917 bcopy(&iv
[0], &iv
[4], 4);
923 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: "
924 "unsupported ivlen/blocklen: %d %d\n",
925 algo
->name
, ivlen
, blocklen
));
930 if (m
->m_pkthdr
.len
< bodyoff
) {
931 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: bad len %d/%lu\n",
932 algo
->name
, m
->m_pkthdr
.len
, (unsigned long)bodyoff
));
936 if ((m
->m_pkthdr
.len
- bodyoff
) % blocklen
) {
937 ipseclog((LOG_ERR
, "esp_cbc_encrypt %s: "
938 "payload length must be multiple of %lu\n",
939 algo
->name
, (unsigned long)algo
->padbound
));
946 soff
= doff
= sn
= dn
= 0;
950 while (soff
< bodyoff
) {
951 if (soff
+ s
->m_len
> bodyoff
) {
962 /* skip over empty mbuf */
963 while (s
&& s
->m_len
== 0)
966 while (soff
< m
->m_pkthdr
.len
) {
968 if (sn
+ blocklen
<= s
->m_len
) {
969 /* body is continuous */
970 sp
= mtod(s
, u_int8_t
*) + sn
;
972 /* body is non-continuous */
973 m_copydata(s
, sn
, blocklen
, sbuf
);
978 if (!d
|| dn
+ blocklen
> d
->m_len
) {
981 MGET(d
, M_DONTWAIT
, MT_DATA
);
982 i
= m
->m_pkthdr
.len
- (soff
+ sn
);
984 MCLGET(d
, M_DONTWAIT
);
985 if ((d
->m_flags
& M_EXT
) == 0) {
1001 d
->m_len
= (M_TRAILINGSPACE(d
) / blocklen
) * blocklen
;
1010 for (i
= 0; i
< blocklen
; i
++)
1014 (*algo
->blockencrypt
)(algo
, sav
, sp
, mtod(d
, u_int8_t
*) + dn
);
1017 ivp
= mtod(d
, u_int8_t
*) + dn
;
1022 /* find the next source block */
1023 while (s
&& sn
>= s
->m_len
) {
1030 m_freem(scut
->m_next
);
1031 scut
->m_len
= scutoff
;
1035 bzero(iv
, sizeof(iv
));
1036 bzero(sbuf
, sizeof(sbuf
));
1038 key_sa_stir_iv(sav
);
1043 /*------------------------------------------------------------*/
1045 /* does not free m0 on error */
1047 esp_auth(m0
, skip
, length
, sav
, sum
)
1049 size_t skip
; /* offset to ESP header */
1050 size_t length
; /* payload length */
1051 struct secasvar
*sav
;
1056 struct ah_algorithm_state s
;
1057 u_char sumbuf
[AH_MAXSUMSIZE
];
1058 const struct ah_algorithm
*algo
;
1063 if (m0
->m_pkthdr
.len
< skip
) {
1064 ipseclog((LOG_DEBUG
, "esp_auth: mbuf length < skip\n"));
1067 if (m0
->m_pkthdr
.len
< skip
+ length
) {
1068 ipseclog((LOG_DEBUG
,
1069 "esp_auth: mbuf length < skip + length\n"));
1073 KERNEL_DEBUG(DBG_FNC_ESPAUTH
| DBG_FUNC_START
, skip
,length
,0,0,0);
1075 * length of esp part (excluding authentication data) must be 4n,
1076 * since nexthdr must be at offset 4n+3.
1079 ipseclog((LOG_ERR
, "esp_auth: length is not multiple of 4\n"));
1080 KERNEL_DEBUG(DBG_FNC_ESPAUTH
| DBG_FUNC_END
, 1,0,0,0,0);
1084 ipseclog((LOG_DEBUG
, "esp_auth: NULL SA passed\n"));
1085 KERNEL_DEBUG(DBG_FNC_ESPAUTH
| DBG_FUNC_END
, 2,0,0,0,0);
1088 algo
= ah_algorithm_lookup(sav
->alg_auth
);
1091 "esp_auth: bad ESP auth algorithm passed: %d\n",
1093 KERNEL_DEBUG(DBG_FNC_ESPAUTH
| DBG_FUNC_END
, 3,0,0,0,0);
1100 siz
= (((*algo
->sumsiz
)(sav
) + 3) & ~(4 - 1));
1101 if (sizeof(sumbuf
) < siz
) {
1102 ipseclog((LOG_DEBUG
,
1103 "esp_auth: AH_MAXSUMSIZE is too small: siz=%lu\n",
1105 KERNEL_DEBUG(DBG_FNC_ESPAUTH
| DBG_FUNC_END
, 4,0,0,0,0);
1109 /* skip the header */
1112 panic("mbuf chain?");
1113 if (m
->m_len
<= skip
) {
1123 error
= (*algo
->init
)(&s
, sav
);
1125 KERNEL_DEBUG(DBG_FNC_ESPAUTH
| DBG_FUNC_END
, 5,0,0,0,0);
1128 lck_mtx_unlock(sadb_mutex
);
1129 while (0 < length
) {
1131 panic("mbuf chain?");
1133 if (m
->m_len
- off
< length
) {
1134 (*algo
->update
)(&s
, mtod(m
, u_char
*) + off
,
1136 length
-= m
->m_len
- off
;
1140 (*algo
->update
)(&s
, mtod(m
, u_char
*) + off
, length
);
1144 (*algo
->result
)(&s
, sumbuf
);
1145 bcopy(sumbuf
, sum
, siz
); /*XXX*/
1146 lck_mtx_lock(sadb_mutex
);
1147 KERNEL_DEBUG(DBG_FNC_ESPAUTH
| DBG_FUNC_END
, 6,0,0,0,0);