1 /* $NetBSD: xform_esp.c,v 1.21 2009/03/18 17:06:52 cegger Exp $ */
2 /* $FreeBSD: src/sys/netipsec/xform_esp.c,v 1.2.2.1 2003/01/24 05:11:36 sam Exp $ */
3 /* $OpenBSD: ip_esp.c,v 1.69 2001/06/26 06:18:59 angelos Exp $ */
6 * The authors of this code are John Ioannidis (ji@tla.org),
7 * Angelos D. Keromytis (kermit@csd.uch.gr) and
8 * Niels Provos (provos@physnet.uni-hamburg.de).
10 * The original version of this code was written by John Ioannidis
11 * for BSD/OS in Athens, Greece, in November 1995.
13 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
14 * by Angelos D. Keromytis.
16 * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
19 * Additional features in 1999 by Angelos D. Keromytis.
21 * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
22 * Angelos D. Keromytis and Niels Provos.
23 * Copyright (c) 2001 Angelos D. Keromytis.
25 * Permission to use, copy, and modify this software with or without fee
26 * is hereby granted, provided that this entire notice is included in
27 * all copies of any software which is or includes a copy or
28 * modification of this software.
29 * You may use this code under the GNU public license if you so wish. Please
30 * contribute changes back to the authors under this freer than GPL license
31 * so that we may further the use of strong encryption without limitations to
34 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
35 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
36 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
37 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
41 #include <sys/cdefs.h>
42 __KERNEL_RCSID(0, "$NetBSD: xform_esp.c,v 1.21 2009/03/18 17:06:52 cegger Exp $");
46 #include "opt_inet6.h"
49 #include <sys/param.h>
50 #include <sys/systm.h>
52 #include <sys/socket.h>
53 #include <sys/syslog.h>
54 #include <sys/kernel.h>
55 /*#include <sys/random.h>*/
56 #include <sys/sysctl.h>
60 #include <netinet/in.h>
61 #include <netinet/in_systm.h>
62 #include <netinet/ip.h>
63 #include <netinet/ip_ecn.h>
64 #include <netinet/ip6.h>
66 #include <net/route.h>
67 #include <netipsec/ipsec.h>
68 #include <netipsec/ipsec_private.h>
69 #include <netipsec/ah.h>
70 #include <netipsec/ah_var.h>
71 #include <netipsec/esp.h>
72 #include <netipsec/esp_var.h>
73 #include <netipsec/xform.h>
76 #include <netinet6/ip6_var.h>
77 #include <netipsec/ipsec6.h>
79 # include <netinet6/ip6_ecn.h>
83 #include <netipsec/key.h>
84 #include <netipsec/key_debug.h>
86 #include <netipsec/ipsec_osdep.h>
88 #include <opencrypto/cryptodev.h>
89 #include <opencrypto/xform.h>
91 percpu_t
*espstat_percpu
;
96 SYSCTL_DECL(_net_inet_esp
);
97 SYSCTL_INT(_net_inet_esp
, OID_AUTO
,
98 esp_enable
, CTLFLAG_RW
, &esp_enable
, 0, "");
99 SYSCTL_STRUCT(_net_inet_esp
, IPSECCTL_STATS
,
100 stats
, CTLFLAG_RD
, &espstat
, espstat
, "");
101 #endif /* __FreeBSD__ */
103 static int esp_max_ivlen
; /* max iv length over all algorithms */
105 static int esp_input_cb(struct cryptop
*op
);
106 static int esp_output_cb(struct cryptop
*crp
);
109 * NB: this is public for use by the PF_KEY support.
110 * NB: if you add support here; be sure to add code to esp_attach below!
113 esp_algorithm_lookup(int alg
)
115 if (alg
>= ESP_ALG_MAX
)
118 case SADB_EALG_DESCBC
:
119 return &enc_xform_des
;
120 case SADB_EALG_3DESCBC
:
121 return &enc_xform_3des
;
122 case SADB_X_EALG_AES
:
123 return &enc_xform_rijndael128
;
124 case SADB_X_EALG_BLOWFISHCBC
:
125 return &enc_xform_blf
;
126 case SADB_X_EALG_CAST128CBC
:
127 return &enc_xform_cast5
;
128 case SADB_X_EALG_SKIPJACK
:
129 return &enc_xform_skipjack
;
131 return &enc_xform_null
;
137 esp_hdrsiz(struct secasvar
*sav
)
142 /*XXX not right for null algorithm--does it matter??*/
143 IPSEC_ASSERT(sav
->tdb_encalgxform
!= NULL
,
144 ("esp_hdrsiz: SA with null xform"));
145 if (sav
->flags
& SADB_X_EXT_OLD
)
146 size
= sizeof (struct esp
);
148 size
= sizeof (struct newesp
);
149 size
+= sav
->tdb_encalgxform
->blocksize
+ 9;
150 /*XXX need alg check???*/
151 if (sav
->tdb_authalgxform
!= NULL
&& sav
->replay
)
152 size
+= ah_hdrsiz(sav
);
156 * + max iv length for CBC mode
158 * + sizeof (pad length field)
159 * + sizeof (next header field)
160 * + max icv supported.
162 size
= sizeof (struct newesp
) + esp_max_ivlen
+ 9 + 16;
168 * esp_init() is called when an SPI is being set up.
171 esp_init(struct secasvar
*sav
, struct xformsw
*xsp
)
173 struct enc_xform
*txform
;
174 struct cryptoini cria
, crie
;
178 txform
= esp_algorithm_lookup(sav
->alg_enc
);
179 if (txform
== NULL
) {
180 DPRINTF(("esp_init: unsupported encryption algorithm %d\n",
184 if (sav
->key_enc
== NULL
) {
185 DPRINTF(("esp_init: no encoding key for %s algorithm\n",
189 if ((sav
->flags
&(SADB_X_EXT_OLD
|SADB_X_EXT_IV4B
)) == SADB_X_EXT_IV4B
) {
190 DPRINTF(("esp_init: 4-byte IV not supported with protocol\n"));
193 keylen
= _KEYLEN(sav
->key_enc
);
194 if (txform
->minkey
> keylen
|| keylen
> txform
->maxkey
) {
195 DPRINTF(("esp_init: invalid key length %u, must be in "
196 "the range [%u..%u] for algorithm %s\n",
197 keylen
, txform
->minkey
, txform
->maxkey
,
203 * NB: The null xform needs a non-zero blocksize to keep the
204 * crypto code happy but if we use it to set ivlen then
205 * the ESP header will be processed incorrectly. The
206 * compromise is to force it to zero here.
208 sav
->ivlen
= (txform
== &enc_xform_null
? 0 : txform
->blocksize
);
209 sav
->iv
= malloc(sav
->ivlen
, M_SECA
, M_WAITOK
);
210 if (sav
->iv
== NULL
) {
211 DPRINTF(("esp_init: no memory for IV\n"));
214 key_randomfill(sav
->iv
, sav
->ivlen
); /*XXX*/
217 * Setup AH-related state.
219 if (sav
->alg_auth
!= 0) {
220 error
= ah_init0(sav
, xsp
, &cria
);
225 /* NB: override anything set in ah_init0 */
226 sav
->tdb_xform
= xsp
;
227 sav
->tdb_encalgxform
= txform
;
229 /* Initialize crypto session. */
230 memset(&crie
, 0, sizeof (crie
));
231 crie
.cri_alg
= sav
->tdb_encalgxform
->type
;
232 crie
.cri_klen
= _KEYBITS(sav
->key_enc
);
233 crie
.cri_key
= _KEYBUF(sav
->key_enc
);
236 mutex_spin_enter(&crypto_mtx
);
237 if (sav
->tdb_authalgxform
&& sav
->tdb_encalgxform
) {
238 /* init both auth & enc */
239 crie
.cri_next
= &cria
;
240 error
= crypto_newsession(&sav
->tdb_cryptoid
,
241 &crie
, crypto_support
);
242 } else if (sav
->tdb_encalgxform
) {
243 error
= crypto_newsession(&sav
->tdb_cryptoid
,
244 &crie
, crypto_support
);
245 } else if (sav
->tdb_authalgxform
) {
246 error
= crypto_newsession(&sav
->tdb_cryptoid
,
247 &cria
, crypto_support
);
249 /* XXX cannot happen? */
250 DPRINTF(("esp_init: no encoding OR authentication xform!\n"));
253 mutex_spin_exit(&crypto_mtx
);
261 esp_zeroize(struct secasvar
*sav
)
263 /* NB: ah_zerorize free's the crypto session state */
264 int error
= ah_zeroize(sav
);
267 memset(_KEYBUF(sav
->key_enc
), 0, _KEYLEN(sav
->key_enc
));
268 /* NB: sav->iv is freed elsewhere, even though we malloc it! */
269 sav
->tdb_encalgxform
= NULL
;
270 sav
->tdb_xform
= NULL
;
275 * ESP input processing, called (eventually) through the protocol switch.
278 esp_input(struct mbuf
*m
, struct secasvar
*sav
, int skip
, int protoff
)
280 struct auth_hash
*esph
;
281 struct enc_xform
*espx
;
282 struct tdb_ident
*tdbi
;
283 struct tdb_crypto
*tc
;
284 int plen
, alen
, hlen
;
288 struct cryptodesc
*crde
;
291 IPSEC_SPLASSERT_SOFTNET("esp_input");
293 IPSEC_ASSERT(sav
!= NULL
, ("esp_input: null SA"));
294 IPSEC_ASSERT(sav
->tdb_encalgxform
!= NULL
,
295 ("esp_input: null encoding xform"));
296 IPSEC_ASSERT((skip
&3) == 0 && (m
->m_pkthdr
.len
&3) == 0,
297 ("esp_input: misaligned packet, skip %u pkt len %u",
298 skip
, m
->m_pkthdr
.len
));
300 /* XXX don't pullup, just copy header */
301 IP6_EXTHDR_GET(esp
, struct newesp
*, m
, skip
, sizeof (struct newesp
));
303 esph
= sav
->tdb_authalgxform
;
304 espx
= sav
->tdb_encalgxform
;
306 /* Determine the ESP header length */
307 if (sav
->flags
& SADB_X_EXT_OLD
)
308 hlen
= sizeof (struct esp
) + sav
->ivlen
;
310 hlen
= sizeof (struct newesp
) + sav
->ivlen
;
311 /* Authenticator hash size */
312 alen
= esph
? AH_HMAC_HASHLEN
: 0;
315 * Verify payload length is multiple of encryption algorithm
318 * NB: This works for the null algorithm because the blocksize
319 * is 4 and all packets must be 4-byte aligned regardless
322 plen
= m
->m_pkthdr
.len
- (skip
+ hlen
+ alen
);
323 if ((plen
& (espx
->blocksize
- 1)) || (plen
<= 0)) {
324 DPRINTF(("esp_input: "
325 "payload of %d octets not a multiple of %d octets,"
327 plen
, espx
->blocksize
,
328 ipsec_address(&sav
->sah
->saidx
.dst
),
329 (u_long
) ntohl(sav
->spi
)));
330 ESP_STATINC(ESP_STAT_BADILEN
);
336 * Check sequence number.
338 if (esph
&& sav
->replay
&& !ipsec_chkreplay(ntohl(esp
->esp_seq
), sav
)) {
339 DPRINTF(("esp_input: packet replay check for %s\n",
340 ipsec_logsastr(sav
))); /*XXX*/
341 ESP_STATINC(ESP_STAT_REPLAY
);
343 return ENOBUFS
; /*XXX*/
346 /* Update the counters */
347 ESP_STATADD(ESP_STAT_IBYTES
, m
->m_pkthdr
.len
- skip
- hlen
- alen
);
349 /* Find out if we've already done crypto */
350 for (mtag
= m_tag_find(m
, PACKET_TAG_IPSEC_IN_CRYPTO_DONE
, NULL
);
352 mtag
= m_tag_find(m
, PACKET_TAG_IPSEC_IN_CRYPTO_DONE
, mtag
)) {
353 tdbi
= (struct tdb_ident
*) (mtag
+ 1);
354 if (tdbi
->proto
== sav
->sah
->saidx
.proto
&&
355 tdbi
->spi
== sav
->spi
&&
356 !memcmp(&tdbi
->dst
, &sav
->sah
->saidx
.dst
,
357 sizeof(union sockaddr_union
)))
361 /* Get crypto descriptors */
362 crp
= crypto_getreq(esph
&& espx
? 2 : 1);
364 DPRINTF(("esp_input: failed to acquire crypto descriptors\n"));
365 ESP_STATINC(ESP_STAT_CRYPTO
);
370 /* Get IPsec-specific opaque pointer */
371 if (esph
== NULL
|| mtag
!= NULL
)
372 tc
= (struct tdb_crypto
*) malloc(sizeof(struct tdb_crypto
),
373 M_XDATA
, M_NOWAIT
|M_ZERO
);
375 tc
= (struct tdb_crypto
*) malloc(sizeof(struct tdb_crypto
) + alen
,
376 M_XDATA
, M_NOWAIT
|M_ZERO
);
379 DPRINTF(("esp_input: failed to allocate tdb_crypto\n"));
380 ESP_STATINC(ESP_STAT_CRYPTO
);
388 struct cryptodesc
*crda
= crp
->crp_desc
;
390 IPSEC_ASSERT(crda
!= NULL
, ("esp_input: null ah crypto descriptor"));
392 /* Authentication descriptor */
393 crda
->crd_skip
= skip
;
394 crda
->crd_len
= m
->m_pkthdr
.len
- (skip
+ alen
);
395 crda
->crd_inject
= m
->m_pkthdr
.len
- alen
;
397 crda
->crd_alg
= esph
->type
;
398 crda
->crd_key
= _KEYBUF(sav
->key_auth
);
399 crda
->crd_klen
= _KEYBITS(sav
->key_auth
);
401 /* Copy the authenticator */
403 m_copydata(m
, m
->m_pkthdr
.len
- alen
, alen
,
406 /* Chain authentication request */
407 crde
= crda
->crd_next
;
409 crde
= crp
->crp_desc
;
412 /* Crypto operation descriptor */
413 crp
->crp_ilen
= m
->m_pkthdr
.len
; /* Total input length */
414 crp
->crp_flags
= CRYPTO_F_IMBUF
;
416 crp
->crp_callback
= esp_input_cb
;
417 crp
->crp_sid
= sav
->tdb_cryptoid
;
418 crp
->crp_opaque
= tc
;
420 /* These are passed as-is to the callback */
421 tc
->tc_spi
= sav
->spi
;
422 tc
->tc_dst
= sav
->sah
->saidx
.dst
;
423 tc
->tc_proto
= sav
->sah
->saidx
.proto
;
424 tc
->tc_protoff
= protoff
;
427 /* Decryption descriptor */
429 IPSEC_ASSERT(crde
!= NULL
, ("esp_input: null esp crypto descriptor"));
430 crde
->crd_skip
= skip
+ hlen
;
431 crde
->crd_len
= m
->m_pkthdr
.len
- (skip
+ hlen
+ alen
);
432 crde
->crd_inject
= skip
+ hlen
- sav
->ivlen
;
434 crde
->crd_alg
= espx
->type
;
435 crde
->crd_key
= _KEYBUF(sav
->key_enc
);
436 crde
->crd_klen
= _KEYBITS(sav
->key_enc
);
441 return crypto_dispatch(crp
);
443 return esp_input_cb(crp
);
447 #define IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff, mtag) do { \
448 if (saidx->dst.sa.sa_family == AF_INET6) { \
449 error = ipsec6_common_input_cb(m, sav, skip, protoff, mtag); \
451 error = ipsec4_common_input_cb(m, sav, skip, protoff, mtag); \
455 #define IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff, mtag) \
456 (error = ipsec4_common_input_cb(m, sav, skip, protoff, mtag))
460 * ESP input callback from the crypto driver.
463 esp_input_cb(struct cryptop
*crp
)
465 u_int8_t lastthree
[3], aalg
[AH_HMAC_HASHLEN
];
466 int s
, hlen
, skip
, protoff
, error
;
468 struct cryptodesc
*crd
;
469 struct auth_hash
*esph
;
470 struct enc_xform
*espx
;
471 struct tdb_crypto
*tc
;
473 struct secasvar
*sav
;
474 struct secasindex
*saidx
;
479 struct m_tag
* tag
= NULL
;
483 IPSEC_ASSERT(crd
!= NULL
, ("esp_input_cb: null crypto descriptor!"));
485 tc
= (struct tdb_crypto
*) crp
->crp_opaque
;
486 IPSEC_ASSERT(tc
!= NULL
, ("esp_input_cb: null opaque crypto data area!"));
488 protoff
= tc
->tc_protoff
;
489 mtag
= (struct m_tag
*) tc
->tc_ptr
;
490 m
= (struct mbuf
*) crp
->crp_buf
;
493 /* find the source port for NAT-T */
494 if ((tag
= m_tag_find(m
, PACKET_TAG_IPSEC_NAT_T_PORTS
, NULL
))) {
495 sport
= ((u_int16_t
*)(tag
+ 1))[0];
496 dport
= ((u_int16_t
*)(tag
+ 1))[1];
502 sav
= KEY_ALLOCSA(&tc
->tc_dst
, tc
->tc_proto
, tc
->tc_spi
, sport
, dport
);
504 ESP_STATINC(ESP_STAT_NOTDB
);
505 DPRINTF(("esp_input_cb: SA expired while in crypto "
506 "(SA %s/%08lx proto %u)\n", ipsec_address(&tc
->tc_dst
),
507 (u_long
) ntohl(tc
->tc_spi
), tc
->tc_proto
));
508 error
= ENOBUFS
; /*XXX*/
512 saidx
= &sav
->sah
->saidx
;
513 IPSEC_ASSERT(saidx
->dst
.sa
.sa_family
== AF_INET
||
514 saidx
->dst
.sa
.sa_family
== AF_INET6
,
515 ("ah_input_cb: unexpected protocol family %u",
516 saidx
->dst
.sa
.sa_family
));
518 esph
= sav
->tdb_authalgxform
;
519 espx
= sav
->tdb_encalgxform
;
521 /* Check for crypto errors */
522 if (crp
->crp_etype
) {
523 /* Reset the session ID */
524 if (sav
->tdb_cryptoid
!= 0)
525 sav
->tdb_cryptoid
= crp
->crp_sid
;
527 if (crp
->crp_etype
== EAGAIN
) {
530 return crypto_dispatch(crp
);
533 ESP_STATINC(ESP_STAT_NOXFORM
);
534 DPRINTF(("esp_input_cb: crypto error %d\n", crp
->crp_etype
));
535 error
= crp
->crp_etype
;
539 /* Shouldn't happen... */
541 ESP_STATINC(ESP_STAT_CRYPTO
);
542 DPRINTF(("esp_input_cb: bogus returned buffer from crypto\n"));
546 ESP_STATINC(ESP_STAT_HIST
+ sav
->alg_enc
);
548 /* If authentication was performed, check now. */
551 * If we have a tag, it means an IPsec-aware NIC did
552 * the verification for us. Otherwise we need to
553 * check the authentication calculation.
555 AH_STATINC(AH_STAT_HIST
+ sav
->alg_auth
);
557 /* Copy the authenticator from the packet */
558 m_copydata(m
, m
->m_pkthdr
.len
- esph
->authsize
,
559 esph
->authsize
, aalg
);
563 /* Verify authenticator */
564 if (memcmp(ptr
, aalg
, esph
->authsize
) != 0) {
565 DPRINTF(("esp_input_cb: "
566 "authentication hash mismatch for packet in SA %s/%08lx\n",
567 ipsec_address(&saidx
->dst
),
568 (u_long
) ntohl(sav
->spi
)));
569 ESP_STATINC(ESP_STAT_BADAUTH
);
575 /* Remove trailing authenticator */
576 m_adj(m
, -(esph
->authsize
));
579 /* Release the crypto descriptors */
580 free(tc
, M_XDATA
), tc
= NULL
;
581 crypto_freereq(crp
), crp
= NULL
;
584 * Packet is now decrypted.
586 m
->m_flags
|= M_DECRYPTED
;
589 * Update replay sequence number, if appropriate.
594 m_copydata(m
, skip
+ offsetof(struct newesp
, esp_seq
),
596 if (ipsec_updatereplay(ntohl(seq
), sav
)) {
597 DPRINTF(("%s: packet replay check for %s\n", __func__
,
598 ipsec_logsastr(sav
)));
599 ESP_STATINC(ESP_STAT_REPLAY
);
605 /* Determine the ESP header length */
606 if (sav
->flags
& SADB_X_EXT_OLD
)
607 hlen
= sizeof (struct esp
) + sav
->ivlen
;
609 hlen
= sizeof (struct newesp
) + sav
->ivlen
;
611 /* Remove the ESP header and IV from the mbuf. */
612 error
= m_striphdr(m
, skip
, hlen
);
614 ESP_STATINC(ESP_STAT_HDROPS
);
615 DPRINTF(("esp_input_cb: bad mbuf chain, SA %s/%08lx\n",
616 ipsec_address(&sav
->sah
->saidx
.dst
),
617 (u_long
) ntohl(sav
->spi
)));
621 /* Save the last three bytes of decrypted data */
622 m_copydata(m
, m
->m_pkthdr
.len
- 3, 3, lastthree
);
624 /* Verify pad length */
625 if (lastthree
[1] + 2 > m
->m_pkthdr
.len
- skip
) {
626 ESP_STATINC(ESP_STAT_BADILEN
);
627 DPRINTF(("esp_input_cb: invalid padding length %d "
628 "for %u byte packet in SA %s/%08lx\n",
629 lastthree
[1], m
->m_pkthdr
.len
- skip
,
630 ipsec_address(&sav
->sah
->saidx
.dst
),
631 (u_long
) ntohl(sav
->spi
)));
636 /* Verify correct decryption by checking the last padding bytes */
637 if ((sav
->flags
& SADB_X_EXT_PMASK
) != SADB_X_EXT_PRAND
) {
638 if (lastthree
[1] != lastthree
[0] && lastthree
[1] != 0) {
639 ESP_STATINC(ESP_STAT_BADENC
);
640 DPRINTF(("esp_input_cb: decryption failed "
641 "for packet in SA %s/%08lx\n",
642 ipsec_address(&sav
->sah
->saidx
.dst
),
643 (u_long
) ntohl(sav
->spi
)));
644 DPRINTF(("esp_input_cb: %x %x\n", lastthree
[0], lastthree
[1]));
650 /* Trim the mbuf chain to remove trailing authenticator and padding */
651 m_adj(m
, -(lastthree
[1] + 2));
653 /* Restore the Next Protocol field */
654 m
= m_copyback_cow(m
, protoff
, sizeof (u_int8_t
), lastthree
+ 2,
658 ESP_STATINC(ESP_STAT_CRYPTO
);
659 DPRINTF(("esp_input_cb: failed to allocate mbuf\n"));
664 IPSEC_COMMON_INPUT_CB(m
, sav
, skip
, protoff
, mtag
);
683 * ESP output routine, called by ipsec[46]_process_packet().
688 struct ipsecrequest
*isr
,
694 struct enc_xform
*espx
;
695 struct auth_hash
*esph
;
696 int hlen
, rlen
, plen
, padding
, blks
, alen
, i
, roff
;
697 struct mbuf
*mo
= (struct mbuf
*) NULL
;
698 struct tdb_crypto
*tc
;
699 struct secasvar
*sav
;
700 struct secasindex
*saidx
;
703 int error
, maxpacketsize
;
705 struct cryptodesc
*crde
= NULL
, *crda
= NULL
;
708 IPSEC_SPLASSERT_SOFTNET("esp_output");
711 IPSEC_ASSERT(sav
!= NULL
, ("esp_output: null SA"));
712 esph
= sav
->tdb_authalgxform
;
713 espx
= sav
->tdb_encalgxform
;
714 IPSEC_ASSERT(espx
!= NULL
, ("esp_output: null encoding xform"));
716 if (sav
->flags
& SADB_X_EXT_OLD
)
717 hlen
= sizeof (struct esp
) + sav
->ivlen
;
719 hlen
= sizeof (struct newesp
) + sav
->ivlen
;
721 rlen
= m
->m_pkthdr
.len
- skip
; /* Raw payload length. */
723 * NB: The null encoding transform has a blocksize of 4
724 * so that headers are properly aligned.
726 blks
= espx
->blocksize
; /* IV blocksize */
728 /* XXX clamp padding length a la KAME??? */
729 padding
= ((blks
- ((rlen
+ 2) % blks
)) % blks
) + 2;
730 plen
= rlen
+ padding
; /* Padded payload length. */
733 alen
= AH_HMAC_HASHLEN
;
737 ESP_STATINC(ESP_STAT_OUTPUT
);
739 saidx
= &sav
->sah
->saidx
;
740 /* Check for maximum packet size violations. */
741 switch (saidx
->dst
.sa
.sa_family
) {
744 maxpacketsize
= IP_MAXPACKET
;
749 maxpacketsize
= IPV6_MAXPACKET
;
753 DPRINTF(("esp_output: unknown/unsupported protocol "
754 "family %d, SA %s/%08lx\n",
755 saidx
->dst
.sa
.sa_family
, ipsec_address(&saidx
->dst
),
756 (u_long
) ntohl(sav
->spi
)));
757 ESP_STATINC(ESP_STAT_NOPF
);
758 error
= EPFNOSUPPORT
;
761 if (skip
+ hlen
+ rlen
+ padding
+ alen
> maxpacketsize
) {
762 DPRINTF(("esp_output: packet in SA %s/%08lx got too big "
763 "(len %u, max len %u)\n",
764 ipsec_address(&saidx
->dst
), (u_long
) ntohl(sav
->spi
),
765 skip
+ hlen
+ rlen
+ padding
+ alen
, maxpacketsize
));
766 ESP_STATINC(ESP_STAT_TOOBIG
);
771 /* Update the counters. */
772 ESP_STATADD(ESP_STAT_OUTPUT
, m
->m_pkthdr
.len
- skip
);
776 DPRINTF(("esp_output: cannot clone mbuf chain, SA %s/%08lx\n",
777 ipsec_address(&saidx
->dst
), (u_long
) ntohl(sav
->spi
)));
778 ESP_STATINC(ESP_STAT_HDROPS
);
783 /* Inject ESP header. */
784 mo
= m_makespace(m
, skip
, hlen
, &roff
);
786 DPRINTF(("esp_output: failed to inject %u byte ESP hdr for SA "
788 hlen
, ipsec_address(&saidx
->dst
),
789 (u_long
) ntohl(sav
->spi
)));
790 ESP_STATINC(ESP_STAT_HDROPS
); /* XXX diffs from openbsd */
795 /* Initialize ESP header. */
796 memcpy(mtod(mo
, char *) + roff
, &sav
->spi
, sizeof(u_int32_t
));
801 /* Emulate replay attack when ipsec_replay is TRUE. */
804 sav
->replay
->count
++;
806 replay
= htonl(sav
->replay
->count
);
808 mtod(mo
,char *) + roff
+ sizeof(u_int32_t
),
813 * Add padding -- better to do it ourselves than use the crypto engine,
814 * although if/when we support compression, we'd have to do that.
816 pad
= (u_char
*) m_pad(m
, padding
+ alen
);
818 DPRINTF(("esp_output: m_pad failed for SA %s/%08lx\n",
819 ipsec_address(&saidx
->dst
), (u_long
) ntohl(sav
->spi
)));
820 m
= NULL
; /* NB: free'd by m_pad */
826 * Add padding: random, zero, or self-describing.
827 * XXX catch unexpected setting
829 switch (sav
->flags
& SADB_X_EXT_PMASK
) {
830 case SADB_X_EXT_PRAND
:
831 (void) read_random(pad
, padding
- 2);
833 case SADB_X_EXT_PZERO
:
834 memset(pad
, 0, padding
- 2);
836 case SADB_X_EXT_PSEQ
:
837 for (i
= 0; i
< padding
- 2; i
++)
842 /* Fix padding length and Next Protocol in padding itself. */
843 pad
[padding
- 2] = padding
- 2;
844 m_copydata(m
, protoff
, sizeof(u_int8_t
), pad
+ padding
- 1);
846 /* Fix Next Protocol in IPv4/IPv6 header. */
848 m_copyback(m
, protoff
, sizeof(u_int8_t
), (u_char
*) &prot
);
850 /* Get crypto descriptors. */
851 crp
= crypto_getreq(esph
&& espx
? 2 : 1);
853 DPRINTF(("esp_output: failed to acquire crypto descriptors\n"));
854 ESP_STATINC(ESP_STAT_CRYPTO
);
860 crde
= crp
->crp_desc
;
861 crda
= crde
->crd_next
;
863 /* Encryption descriptor. */
864 crde
->crd_skip
= skip
+ hlen
;
865 crde
->crd_len
= m
->m_pkthdr
.len
- (skip
+ hlen
+ alen
);
866 crde
->crd_flags
= CRD_F_ENCRYPT
;
867 crde
->crd_inject
= skip
+ hlen
- sav
->ivlen
;
869 /* Encryption operation. */
870 crde
->crd_alg
= espx
->type
;
871 crde
->crd_key
= _KEYBUF(sav
->key_enc
);
872 crde
->crd_klen
= _KEYBITS(sav
->key_enc
);
875 crda
= crp
->crp_desc
;
877 /* IPsec-specific opaque crypto info. */
878 tc
= (struct tdb_crypto
*) malloc(sizeof(struct tdb_crypto
),
879 M_XDATA
, M_NOWAIT
|M_ZERO
);
882 DPRINTF(("esp_output: failed to allocate tdb_crypto\n"));
883 ESP_STATINC(ESP_STAT_CRYPTO
);
888 /* Callback parameters */
890 tc
->tc_spi
= sav
->spi
;
891 tc
->tc_dst
= saidx
->dst
;
892 tc
->tc_proto
= saidx
->proto
;
894 /* Crypto operation descriptor. */
895 crp
->crp_ilen
= m
->m_pkthdr
.len
; /* Total input length. */
896 crp
->crp_flags
= CRYPTO_F_IMBUF
;
898 crp
->crp_callback
= esp_output_cb
;
899 crp
->crp_opaque
= tc
;
900 crp
->crp_sid
= sav
->tdb_cryptoid
;
903 /* Authentication descriptor. */
904 crda
->crd_skip
= skip
;
905 crda
->crd_len
= m
->m_pkthdr
.len
- (skip
+ alen
);
906 crda
->crd_inject
= m
->m_pkthdr
.len
- alen
;
908 /* Authentication operation. */
909 crda
->crd_alg
= esph
->type
;
910 crda
->crd_key
= _KEYBUF(sav
->key_auth
);
911 crda
->crd_klen
= _KEYBITS(sav
->key_auth
);
914 return crypto_dispatch(crp
);
922 * ESP output callback from the crypto driver.
925 esp_output_cb(struct cryptop
*crp
)
927 struct tdb_crypto
*tc
;
928 struct ipsecrequest
*isr
;
929 struct secasvar
*sav
;
933 tc
= (struct tdb_crypto
*) crp
->crp_opaque
;
934 IPSEC_ASSERT(tc
!= NULL
, ("esp_output_cb: null opaque data area!"));
935 m
= (struct mbuf
*) crp
->crp_buf
;
940 sav
= KEY_ALLOCSA(&tc
->tc_dst
, tc
->tc_proto
, tc
->tc_spi
, 0, 0);
942 ESP_STATINC(ESP_STAT_NOTDB
);
943 DPRINTF(("esp_output_cb: SA expired while in crypto "
944 "(SA %s/%08lx proto %u)\n", ipsec_address(&tc
->tc_dst
),
945 (u_long
) ntohl(tc
->tc_spi
), tc
->tc_proto
));
946 error
= ENOBUFS
; /*XXX*/
949 IPSEC_ASSERT(isr
->sav
== sav
,
950 ("esp_output_cb: SA changed was %p now %p\n", isr
->sav
, sav
));
952 /* Check for crypto errors. */
953 if (crp
->crp_etype
) {
954 /* Reset session ID. */
955 if (sav
->tdb_cryptoid
!= 0)
956 sav
->tdb_cryptoid
= crp
->crp_sid
;
958 if (crp
->crp_etype
== EAGAIN
) {
961 return crypto_dispatch(crp
);
964 ESP_STATINC(ESP_STAT_NOXFORM
);
965 DPRINTF(("esp_output_cb: crypto error %d\n", crp
->crp_etype
));
966 error
= crp
->crp_etype
;
970 /* Shouldn't happen... */
972 ESP_STATINC(ESP_STAT_CRYPTO
);
973 DPRINTF(("esp_output_cb: bogus returned buffer from crypto\n"));
977 ESP_STATINC(ESP_STAT_HIST
+ sav
->alg_enc
);
978 if (sav
->tdb_authalgxform
!= NULL
)
979 AH_STATINC(sav
->alg_auth
+ sav
->alg_auth
);
981 /* Release crypto descriptors. */
986 /* Emulate man-in-the-middle attack when ipsec_integrity is TRUE. */
987 if (ipsec_integrity
) {
988 static unsigned char ipseczeroes
[AH_HMAC_HASHLEN
];
989 struct auth_hash
*esph
;
992 * Corrupt HMAC if we want to test integrity verification of
995 esph
= sav
->tdb_authalgxform
;
997 m_copyback(m
, m
->m_pkthdr
.len
- AH_HMAC_HASHLEN
,
998 AH_HMAC_HASHLEN
, ipseczeroes
);
1003 /* NB: m is reclaimed by ipsec_process_done. */
1004 err
= ipsec_process_done(m
, isr
);
1015 crypto_freereq(crp
);
1019 static struct xformsw esp_xformsw
= {
1020 XF_ESP
, XFT_CONF
|XFT_AUTH
, "IPsec ESP",
1021 esp_init
, esp_zeroize
, esp_input
,
1030 espstat_percpu
= percpu_alloc(sizeof(uint64_t) * ESP_NSTATS
);
1032 #define MAXIV(xform) \
1033 if (xform.blocksize > esp_max_ivlen) \
1034 esp_max_ivlen = xform.blocksize \
1037 MAXIV(enc_xform_des
); /* SADB_EALG_DESCBC */
1038 MAXIV(enc_xform_3des
); /* SADB_EALG_3DESCBC */
1039 MAXIV(enc_xform_rijndael128
); /* SADB_X_EALG_AES */
1040 MAXIV(enc_xform_blf
); /* SADB_X_EALG_BLOWFISHCBC */
1041 MAXIV(enc_xform_cast5
); /* SADB_X_EALG_CAST128CBC */
1042 MAXIV(enc_xform_skipjack
); /* SADB_X_EALG_SKIPJACK */
1043 MAXIV(enc_xform_null
); /* SADB_EALG_NULL */
1045 xform_register(&esp_xformsw
);
1049 SYSINIT(esp_xform_init
, SI_SUB_DRIVERS
, SI_ORDER_FIRST
, esp_attach
, NULL
)