1 /* $FreeBSD: src/sys/netipsec/xform_esp.c,v 1.2.2.2 2003/02/26 00:14:05 sam Exp $ */
2 /* $OpenBSD: ip_esp.c,v 1.69 2001/06/26 06:18:59 angelos Exp $ */
4 * The authors of this code are John Ioannidis (ji@tla.org),
5 * Angelos D. Keromytis (kermit@csd.uch.gr) and
6 * Niels Provos (provos@physnet.uni-hamburg.de).
8 * The original version of this code was written by John Ioannidis
9 * for BSD/OS in Athens, Greece, in November 1995.
11 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
12 * by Angelos D. Keromytis.
14 * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
17 * Additional features in 1999 by Angelos D. Keromytis.
19 * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
20 * Angelos D. Keromytis and Niels Provos.
21 * Copyright (c) 2001 Angelos D. Keromytis.
23 * Permission to use, copy, and modify this software with or without fee
24 * is hereby granted, provided that this entire notice is included in
25 * all copies of any software which is or includes a copy or
26 * modification of this software.
27 * You may use this code under the GNU public license if you so wish. Please
28 * contribute changes back to the authors under this freer than GPL license
29 * so that we may further the use of strong encryption without limitations to
32 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
33 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
34 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
35 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
39 #include "opt_inet6.h"
41 #include <sys/param.h>
42 #include <sys/systm.h>
44 #include <sys/socket.h>
45 #include <sys/syslog.h>
46 #include <sys/kernel.h>
47 #include <sys/random.h>
48 #include <sys/sysctl.h>
52 #include <netinet/in.h>
53 #include <netinet/in_systm.h>
54 #include <netinet/ip.h>
55 #include <netinet/ip_ecn.h>
56 #include <netinet/ip6.h>
58 #include <net/route.h>
59 #include <netproto/ipsec/ipsec.h>
60 #include <netproto/ipsec/ah.h>
61 #include <netproto/ipsec/ah_var.h>
62 #include <netproto/ipsec/esp.h>
63 #include <netproto/ipsec/esp_var.h>
64 #include <netproto/ipsec/xform.h>
67 #include <netinet6/ip6_var.h>
68 #include <netproto/ipsec/ipsec6.h>
69 #include <netinet6/ip6_ecn.h>
72 #include <netproto/ipsec/key.h>
73 #include <netproto/ipsec/key_debug.h>
75 #include <opencrypto/cryptodev.h>
76 #include <opencrypto/xform.h>
79 struct espstat espstat
;
81 SYSCTL_DECL(_net_inet_esp
);
82 SYSCTL_INT(_net_inet_esp
, OID_AUTO
,
83 esp_enable
, CTLFLAG_RW
, &esp_enable
, 0, "");
84 SYSCTL_STRUCT(_net_inet_esp
, IPSECCTL_STATS
,
85 stats
, CTLFLAG_RD
, &espstat
, espstat
, "");
87 static int esp_max_ivlen
; /* max iv length over all algorithms */
89 static int esp_input_cb(struct cryptop
*op
);
90 static int esp_output_cb(struct cryptop
*crp
);
93 * NB: this is public for use by the PF_KEY support.
94 * NB: if you add support here; be sure to add code to esp_attach below!
97 esp_algorithm_lookup(int alg
)
99 if (alg
>= ESP_ALG_MAX
)
102 case SADB_EALG_DESCBC
:
103 return &enc_xform_des
;
104 case SADB_EALG_3DESCBC
:
105 return &enc_xform_3des
;
106 case SADB_X_EALG_AES
:
107 return &enc_xform_rijndael128
;
108 case SADB_X_EALG_BLOWFISHCBC
:
109 return &enc_xform_blf
;
110 case SADB_X_EALG_CAST128CBC
:
111 return &enc_xform_cast5
;
112 case SADB_X_EALG_SKIPJACK
:
113 return &enc_xform_skipjack
;
115 return &enc_xform_null
;
121 esp_hdrsiz(struct secasvar
*sav
)
126 /*XXX not right for null algorithm--does it matter??*/
127 KASSERT(sav
->tdb_encalgxform
!= NULL
,
128 ("esp_hdrsiz: SA with null xform"));
129 if (sav
->flags
& SADB_X_EXT_OLD
)
130 size
= sizeof (struct esp
);
132 size
= sizeof (struct newesp
);
133 size
+= sav
->tdb_encalgxform
->blocksize
+ 9;
134 /*XXX need alg check???*/
135 if (sav
->tdb_authalgxform
!= NULL
&& sav
->replay
)
136 size
+= ah_hdrsiz(sav
);
140 * + max iv length for CBC mode
142 * + sizeof (pad length field)
143 * + sizeof (next header field)
144 * + max icv supported.
146 size
= sizeof (struct newesp
) + esp_max_ivlen
+ 9 + 16;
152 * esp_init() is called when an SPI is being set up.
155 esp_init(struct secasvar
*sav
, struct xformsw
*xsp
)
157 struct enc_xform
*txform
;
158 struct cryptoini cria
, crie
;
162 txform
= esp_algorithm_lookup(sav
->alg_enc
);
163 if (txform
== NULL
) {
164 DPRINTF(("esp_init: unsupported encryption algorithm %d\n",
168 if (sav
->key_enc
== NULL
) {
169 DPRINTF(("esp_init: no encoding key for %s algorithm\n",
173 if ((sav
->flags
&(SADB_X_EXT_OLD
|SADB_X_EXT_IV4B
)) == SADB_X_EXT_IV4B
) {
174 DPRINTF(("esp_init: 4-byte IV not supported with protocol\n"));
177 keylen
= _KEYLEN(sav
->key_enc
);
178 if (txform
->minkey
> keylen
|| keylen
> txform
->maxkey
) {
179 DPRINTF(("esp_init: invalid key length %u, must be in "
180 "the range [%u..%u] for algorithm %s\n",
181 keylen
, txform
->minkey
, txform
->maxkey
,
187 * NB: The null xform needs a non-zero blocksize to keep the
188 * crypto code happy but if we use it to set ivlen then
189 * the ESP header will be processed incorrectly. The
190 * compromise is to force it to zero here.
192 sav
->ivlen
= (txform
== &enc_xform_null
? 0 : txform
->blocksize
);
193 sav
->iv
= (caddr_t
) kmalloc(sav
->ivlen
, M_XDATA
, M_WAITOK
);
194 key_randomfill(sav
->iv
, sav
->ivlen
); /*XXX*/
197 * Setup AH-related state.
199 if (sav
->alg_auth
!= 0) {
200 error
= ah_init0(sav
, xsp
, &cria
);
205 /* NB: override anything set in ah_init0 */
206 sav
->tdb_xform
= xsp
;
207 sav
->tdb_encalgxform
= txform
;
209 /* Initialize crypto session. */
210 bzero(&crie
, sizeof (crie
));
211 crie
.cri_alg
= sav
->tdb_encalgxform
->type
;
212 crie
.cri_klen
= _KEYBITS(sav
->key_enc
);
213 crie
.cri_key
= _KEYBUF(sav
->key_enc
);
216 if (sav
->tdb_authalgxform
&& sav
->tdb_encalgxform
) {
217 /* init both auth & enc */
218 crie
.cri_next
= &cria
;
219 error
= crypto_newsession(&sav
->tdb_cryptoid
,
220 &crie
, crypto_support
);
221 } else if (sav
->tdb_encalgxform
) {
222 error
= crypto_newsession(&sav
->tdb_cryptoid
,
223 &crie
, crypto_support
);
224 } else if (sav
->tdb_authalgxform
) {
225 error
= crypto_newsession(&sav
->tdb_cryptoid
,
226 &cria
, crypto_support
);
228 /* XXX cannot happen? */
229 DPRINTF(("esp_init: no encoding OR authentication xform!\n"));
239 esp_zeroize(struct secasvar
*sav
)
241 /* NB: ah_zerorize free's the crypto session state */
242 int error
= ah_zeroize(sav
);
245 bzero(_KEYBUF(sav
->key_enc
), _KEYLEN(sav
->key_enc
));
246 /* NB: sav->iv is freed elsewhere, even though we malloc it! */
247 sav
->tdb_encalgxform
= NULL
;
248 sav
->tdb_xform
= NULL
;
253 * ESP input processing, called (eventually) through the protocol switch.
256 esp_input(struct mbuf
*m
, struct secasvar
*sav
, int skip
, int protoff
)
258 struct auth_hash
*esph
;
259 struct enc_xform
*espx
;
260 struct tdb_ident
*tdbi
;
261 struct tdb_crypto
*tc
;
262 int plen
, alen
, hlen
;
266 struct cryptodesc
*crde
;
269 KASSERT(sav
!= NULL
, ("esp_input: null SA"));
270 KASSERT(sav
->tdb_encalgxform
!= NULL
,
271 ("esp_input: null encoding xform"));
272 KASSERT((skip
&3) == 0 && (m
->m_pkthdr
.len
&3) == 0,
273 ("esp_input: misaligned packet, skip %u pkt len %u",
274 skip
, m
->m_pkthdr
.len
));
276 /* XXX don't pullup, just copy header */
277 IP6_EXTHDR_GET(esp
, struct newesp
*, m
, skip
, sizeof (struct newesp
));
279 esph
= sav
->tdb_authalgxform
;
280 espx
= sav
->tdb_encalgxform
;
282 /* Determine the ESP header length */
283 if (sav
->flags
& SADB_X_EXT_OLD
)
284 hlen
= sizeof (struct esp
) + sav
->ivlen
;
286 hlen
= sizeof (struct newesp
) + sav
->ivlen
;
287 /* Authenticator hash size */
288 alen
= esph
? AH_HMAC_HASHLEN
: 0;
291 * Verify payload length is multiple of encryption algorithm
294 * NB: This works for the null algorithm because the blocksize
295 * is 4 and all packets must be 4-byte aligned regardless
298 plen
= m
->m_pkthdr
.len
- (skip
+ hlen
+ alen
);
299 if ((plen
& (espx
->blocksize
- 1)) || (plen
<= 0)) {
300 DPRINTF(("esp_input: "
301 "payload of %d octets not a multiple of %d octets,"
303 plen
, espx
->blocksize
,
304 ipsec_address(&sav
->sah
->saidx
.dst
),
305 (u_long
) ntohl(sav
->spi
)));
306 espstat
.esps_badilen
++;
312 * Check sequence number.
314 if (esph
&& sav
->replay
&& !ipsec_chkreplay(ntohl(esp
->esp_seq
), sav
)) {
315 DPRINTF(("esp_input: packet replay check for %s\n",
316 ipsec_logsastr(sav
))); /*XXX*/
317 espstat
.esps_replay
++;
319 return ENOBUFS
; /*XXX*/
322 /* Update the counters */
323 espstat
.esps_ibytes
+= m
->m_pkthdr
.len
- skip
- hlen
- alen
;
325 /* Find out if we've already done crypto */
326 for (mtag
= m_tag_find(m
, PACKET_TAG_IPSEC_IN_CRYPTO_DONE
, NULL
);
328 mtag
= m_tag_find(m
, PACKET_TAG_IPSEC_IN_CRYPTO_DONE
, mtag
)) {
329 tdbi
= (struct tdb_ident
*)m_tag_data(mtag
);
330 if (tdbi
->proto
== sav
->sah
->saidx
.proto
&&
331 tdbi
->spi
== sav
->spi
&&
332 !bcmp(&tdbi
->dst
, &sav
->sah
->saidx
.dst
,
333 sizeof(union sockaddr_union
)))
337 /* Get crypto descriptors */
338 crp
= crypto_getreq(esph
&& espx
? 2 : 1);
340 DPRINTF(("esp_input: failed to acquire crypto descriptors\n"));
341 espstat
.esps_crypto
++;
346 /* Get IPsec-specific opaque pointer */
347 if (esph
== NULL
|| mtag
!= NULL
)
348 tc
= kmalloc(sizeof(struct tdb_crypto
),
349 M_XDATA
, M_INTWAIT
| M_ZERO
| M_NULLOK
);
351 tc
= kmalloc(sizeof(struct tdb_crypto
) + alen
,
352 M_XDATA
, M_INTWAIT
| M_ZERO
| M_NULLOK
);
355 DPRINTF(("esp_input: failed to allocate tdb_crypto\n"));
356 espstat
.esps_crypto
++;
361 tc
->tc_ptr
= (caddr_t
) mtag
;
364 struct cryptodesc
*crda
= crp
->crp_desc
;
366 KASSERT(crda
!= NULL
, ("esp_input: null ah crypto descriptor"));
368 /* Authentication descriptor */
369 crda
->crd_skip
= skip
;
370 crda
->crd_len
= m
->m_pkthdr
.len
- (skip
+ alen
);
371 crda
->crd_inject
= m
->m_pkthdr
.len
- alen
;
373 crda
->crd_alg
= esph
->type
;
374 crda
->crd_key
= _KEYBUF(sav
->key_auth
);
375 crda
->crd_klen
= _KEYBITS(sav
->key_auth
);
377 /* Copy the authenticator */
379 m_copydata(m
, m
->m_pkthdr
.len
- alen
, alen
,
382 /* Chain authentication request */
383 crde
= crda
->crd_next
;
385 crde
= crp
->crp_desc
;
388 /* Crypto operation descriptor */
389 crp
->crp_ilen
= m
->m_pkthdr
.len
; /* Total input length */
390 crp
->crp_flags
= CRYPTO_F_IMBUF
;
391 crp
->crp_buf
= (caddr_t
) m
;
392 crp
->crp_callback
= esp_input_cb
;
393 crp
->crp_sid
= sav
->tdb_cryptoid
;
394 crp
->crp_opaque
= (caddr_t
) tc
;
396 /* These are passed as-is to the callback */
397 tc
->tc_spi
= sav
->spi
;
398 tc
->tc_dst
= sav
->sah
->saidx
.dst
;
399 tc
->tc_proto
= sav
->sah
->saidx
.proto
;
400 tc
->tc_protoff
= protoff
;
403 /* Decryption descriptor */
405 KASSERT(crde
!= NULL
, ("esp_input: null esp crypto descriptor"));
406 crde
->crd_skip
= skip
+ hlen
;
407 crde
->crd_len
= m
->m_pkthdr
.len
- (skip
+ hlen
+ alen
);
408 crde
->crd_inject
= skip
+ hlen
- sav
->ivlen
;
410 crde
->crd_alg
= espx
->type
;
411 crde
->crd_key
= _KEYBUF(sav
->key_enc
);
412 crde
->crd_klen
= _KEYBITS(sav
->key_enc
);
417 return crypto_dispatch(crp
);
419 return esp_input_cb(crp
);
423 #define IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff, mtag) do { \
424 if (saidx->dst.sa.sa_family == AF_INET6) { \
425 error = ipsec6_common_input_cb(m, sav, skip, protoff, mtag); \
427 error = ipsec4_common_input_cb(m, sav, skip, protoff, mtag); \
431 #define IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff, mtag) \
432 (error = ipsec4_common_input_cb(m, sav, skip, protoff, mtag))
436 * ESP input callback from the crypto driver.
439 esp_input_cb(struct cryptop
*crp
)
441 u_int8_t lastthree
[3], aalg
[AH_HMAC_HASHLEN
];
442 int hlen
, skip
, protoff
, error
;
444 struct cryptodesc
*crd
;
445 struct auth_hash
*esph
;
446 struct enc_xform
*espx
;
447 struct tdb_crypto
*tc
;
449 struct secasvar
*sav
;
450 struct secasindex
*saidx
;
454 KASSERT(crd
!= NULL
, ("esp_input_cb: null crypto descriptor!"));
456 tc
= (struct tdb_crypto
*) crp
->crp_opaque
;
457 KASSERT(tc
!= NULL
, ("esp_input_cb: null opaque crypto data area!"));
459 protoff
= tc
->tc_protoff
;
460 mtag
= (struct m_tag
*) tc
->tc_ptr
;
461 m
= (struct mbuf
*) crp
->crp_buf
;
465 sav
= KEY_ALLOCSA(&tc
->tc_dst
, tc
->tc_proto
, tc
->tc_spi
);
467 espstat
.esps_notdb
++;
468 DPRINTF(("esp_input_cb: SA expired while in crypto "
469 "(SA %s/%08lx proto %u)\n", ipsec_address(&tc
->tc_dst
),
470 (u_long
) ntohl(tc
->tc_spi
), tc
->tc_proto
));
471 error
= ENOBUFS
; /*XXX*/
475 saidx
= &sav
->sah
->saidx
;
476 KASSERT(saidx
->dst
.sa
.sa_family
== AF_INET
||
477 saidx
->dst
.sa
.sa_family
== AF_INET6
,
478 ("ah_input_cb: unexpected protocol family %u",
479 saidx
->dst
.sa
.sa_family
));
481 esph
= sav
->tdb_authalgxform
;
482 espx
= sav
->tdb_encalgxform
;
484 /* Check for crypto errors */
485 if (crp
->crp_etype
) {
486 /* Reset the session ID */
487 if (sav
->tdb_cryptoid
!= 0)
488 sav
->tdb_cryptoid
= crp
->crp_sid
;
490 if (crp
->crp_etype
== EAGAIN
) {
493 return crypto_dispatch(crp
);
496 espstat
.esps_noxform
++;
497 DPRINTF(("esp_input_cb: crypto error %d\n", crp
->crp_etype
));
498 error
= crp
->crp_etype
;
502 /* Shouldn't happen... */
504 espstat
.esps_crypto
++;
505 DPRINTF(("esp_input_cb: bogus returned buffer from crypto\n"));
509 espstat
.esps_hist
[sav
->alg_enc
]++;
511 /* If authentication was performed, check now. */
514 * If we have a tag, it means an IPsec-aware NIC did
515 * the verification for us. Otherwise we need to
516 * check the authentication calculation.
518 ahstat
.ahs_hist
[sav
->alg_auth
]++;
520 /* Copy the authenticator from the packet */
521 m_copydata(m
, m
->m_pkthdr
.len
- esph
->blocksize
,
522 esph
->blocksize
, aalg
);
524 ptr
= (caddr_t
) (tc
+ 1);
526 /* Verify authenticator */
527 if (bcmp(ptr
, aalg
, esph
->blocksize
) != 0) {
528 DPRINTF(("esp_input_cb: "
529 "authentication hash mismatch for packet in SA %s/%08lx\n",
530 ipsec_address(&saidx
->dst
),
531 (u_long
) ntohl(sav
->spi
)));
532 espstat
.esps_badauth
++;
538 /* Remove trailing authenticator */
539 m_adj(m
, -(esph
->blocksize
));
542 /* Release the crypto descriptors */
543 kfree(tc
, M_XDATA
), tc
= NULL
;
544 crypto_freereq(crp
), crp
= NULL
;
547 * Packet is now decrypted.
549 m
->m_flags
|= M_DECRYPTED
;
552 * Update replay sequence number, if appropriate.
557 m_copydata(m
, skip
+ offsetof(struct newesp
, esp_seq
),
558 sizeof (seq
), (caddr_t
) &seq
);
559 if (ipsec_updatereplay(ntohl(seq
), sav
)) {
560 DPRINTF(("%s: packet replay check for %s\n", __func__
,
561 ipsec_logsastr(sav
)));
562 espstat
.esps_replay
++;
568 /* Determine the ESP header length */
569 if (sav
->flags
& SADB_X_EXT_OLD
)
570 hlen
= sizeof (struct esp
) + sav
->ivlen
;
572 hlen
= sizeof (struct newesp
) + sav
->ivlen
;
574 /* Remove the ESP header and IV from the mbuf. */
575 error
= m_striphdr(m
, skip
, hlen
);
577 espstat
.esps_hdrops
++;
578 DPRINTF(("esp_input_cb: bad mbuf chain, SA %s/%08lx\n",
579 ipsec_address(&sav
->sah
->saidx
.dst
),
580 (u_long
) ntohl(sav
->spi
)));
584 /* Save the last three bytes of decrypted data */
585 m_copydata(m
, m
->m_pkthdr
.len
- 3, 3, lastthree
);
587 /* Verify pad length */
588 if (lastthree
[1] + 2 > m
->m_pkthdr
.len
- skip
) {
589 espstat
.esps_badilen
++;
590 DPRINTF(("esp_input_cb: invalid padding length %d "
591 "for %u byte packet in SA %s/%08lx\n",
592 lastthree
[1], m
->m_pkthdr
.len
- skip
,
593 ipsec_address(&sav
->sah
->saidx
.dst
),
594 (u_long
) ntohl(sav
->spi
)));
599 /* Verify correct decryption by checking the last padding bytes */
600 if ((sav
->flags
& SADB_X_EXT_PMASK
) != SADB_X_EXT_PRAND
) {
601 if (lastthree
[1] != lastthree
[0] && lastthree
[1] != 0) {
602 espstat
.esps_badenc
++;
603 DPRINTF(("esp_input_cb: decryption failed "
604 "for packet in SA %s/%08lx\n",
605 ipsec_address(&sav
->sah
->saidx
.dst
),
606 (u_long
) ntohl(sav
->spi
)));
607 DPRINTF(("esp_input_cb: %x %x\n", lastthree
[0], lastthree
[1]));
613 /* Trim the mbuf chain to remove trailing authenticator and padding */
614 m_adj(m
, -(lastthree
[1] + 2));
616 /* Restore the Next Protocol field */
617 m_copyback(m
, protoff
, sizeof (u_int8_t
), lastthree
+ 2);
619 IPSEC_COMMON_INPUT_CB(m
, sav
, skip
, protoff
, mtag
);
638 * ESP output routine, called by ipsec[46]_process_packet().
643 struct ipsecrequest
*isr
,
649 struct enc_xform
*espx
;
650 struct auth_hash
*esph
;
651 int hlen
, rlen
, plen
, padding
, blks
, alen
, i
, roff
;
652 struct mbuf
*mo
= NULL
;
653 struct tdb_crypto
*tc
;
654 struct secasvar
*sav
;
655 struct secasindex
*saidx
;
658 int error
, maxpacketsize
;
660 struct cryptodesc
*crde
= NULL
, *crda
= NULL
;
664 KASSERT(sav
!= NULL
, ("esp_output: null SA"));
665 esph
= sav
->tdb_authalgxform
;
666 espx
= sav
->tdb_encalgxform
;
667 KASSERT(espx
!= NULL
, ("esp_output: null encoding xform"));
669 if (sav
->flags
& SADB_X_EXT_OLD
)
670 hlen
= sizeof (struct esp
) + sav
->ivlen
;
672 hlen
= sizeof (struct newesp
) + sav
->ivlen
;
674 rlen
= m
->m_pkthdr
.len
- skip
; /* Raw payload length. */
676 * NB: The null encoding transform has a blocksize of 4
677 * so that headers are properly aligned.
679 blks
= espx
->blocksize
; /* IV blocksize */
681 /* XXX clamp padding length a la KAME??? */
682 padding
= ((blks
- ((rlen
+ 2) % blks
)) % blks
) + 2;
683 plen
= rlen
+ padding
; /* Padded payload length. */
686 alen
= AH_HMAC_HASHLEN
;
690 espstat
.esps_output
++;
692 saidx
= &sav
->sah
->saidx
;
693 /* Check for maximum packet size violations. */
694 switch (saidx
->dst
.sa
.sa_family
) {
697 maxpacketsize
= IP_MAXPACKET
;
702 maxpacketsize
= IPV6_MAXPACKET
;
706 DPRINTF(("esp_output: unknown/unsupported protocol "
707 "family %d, SA %s/%08lx\n",
708 saidx
->dst
.sa
.sa_family
, ipsec_address(&saidx
->dst
),
709 (u_long
) ntohl(sav
->spi
)));
711 error
= EPFNOSUPPORT
;
714 if (skip
+ hlen
+ rlen
+ padding
+ alen
> maxpacketsize
) {
715 DPRINTF(("esp_output: packet in SA %s/%08lx got too big "
716 "(len %u, max len %u)\n",
717 ipsec_address(&saidx
->dst
), (u_long
) ntohl(sav
->spi
),
718 skip
+ hlen
+ rlen
+ padding
+ alen
, maxpacketsize
));
719 espstat
.esps_toobig
++;
724 /* Update the counters. */
725 espstat
.esps_obytes
+= m
->m_pkthdr
.len
- skip
;
729 DPRINTF(("esp_output: cannot clone mbuf chain, SA %s/%08lx\n",
730 ipsec_address(&saidx
->dst
), (u_long
) ntohl(sav
->spi
)));
731 espstat
.esps_hdrops
++;
736 /* Inject ESP header. */
737 mo
= m_makespace(m
, skip
, hlen
, &roff
);
739 DPRINTF(("esp_output: failed to inject %u byte ESP hdr for SA "
741 hlen
, ipsec_address(&saidx
->dst
),
742 (u_long
) ntohl(sav
->spi
)));
743 espstat
.esps_hdrops
++; /* XXX diffs from openbsd */
748 /* Initialize ESP header. */
749 bcopy((caddr_t
) &sav
->spi
, mtod(mo
, caddr_t
) + roff
, sizeof(u_int32_t
));
751 u_int32_t replay
= htonl(++(sav
->replay
->count
));
752 bcopy((caddr_t
) &replay
,
753 mtod(mo
, caddr_t
) + roff
+ sizeof(u_int32_t
),
758 * Add padding -- better to do it ourselves than use the crypto engine,
759 * although if/when we support compression, we'd have to do that.
761 pad
= (u_char
*) m_pad(m
, padding
+ alen
);
763 DPRINTF(("esp_output: m_pad failed for SA %s/%08lx\n",
764 ipsec_address(&saidx
->dst
), (u_long
) ntohl(sav
->spi
)));
765 m
= NULL
; /* NB: free'd by m_pad */
771 * Add padding: random, zero, or self-describing.
772 * XXX catch unexpected setting
774 switch (sav
->flags
& SADB_X_EXT_PMASK
) {
775 case SADB_X_EXT_PRAND
:
776 read_random(pad
, padding
- 2);
778 case SADB_X_EXT_PZERO
:
779 bzero(pad
, padding
- 2);
781 case SADB_X_EXT_PSEQ
:
782 for (i
= 0; i
< padding
- 2; i
++)
787 /* Fix padding length and Next Protocol in padding itself. */
788 pad
[padding
- 2] = padding
- 2;
789 m_copydata(m
, protoff
, sizeof(u_int8_t
), pad
+ padding
- 1);
791 /* Fix Next Protocol in IPv4/IPv6 header. */
793 m_copyback(m
, protoff
, sizeof(u_int8_t
), (u_char
*) &prot
);
795 /* Get crypto descriptors. */
796 crp
= crypto_getreq(esph
&& espx
? 2 : 1);
798 DPRINTF(("esp_output: failed to acquire crypto descriptors\n"));
799 espstat
.esps_crypto
++;
805 crde
= crp
->crp_desc
;
806 crda
= crde
->crd_next
;
808 /* Encryption descriptor. */
809 crde
->crd_skip
= skip
+ hlen
;
810 crde
->crd_len
= m
->m_pkthdr
.len
- (skip
+ hlen
+ alen
);
811 crde
->crd_flags
= CRD_F_ENCRYPT
;
812 crde
->crd_inject
= skip
+ hlen
- sav
->ivlen
;
814 /* Encryption operation. */
815 crde
->crd_alg
= espx
->type
;
816 crde
->crd_key
= _KEYBUF(sav
->key_enc
);
817 crde
->crd_klen
= _KEYBITS(sav
->key_enc
);
820 crda
= crp
->crp_desc
;
822 /* IPsec-specific opaque crypto info. */
823 tc
= kmalloc(sizeof(struct tdb_crypto
),
824 M_XDATA
, M_INTWAIT
| M_ZERO
| M_NULLOK
);
827 DPRINTF(("esp_output: failed to allocate tdb_crypto\n"));
828 espstat
.esps_crypto
++;
833 /* Callback parameters */
835 tc
->tc_spi
= sav
->spi
;
836 tc
->tc_dst
= saidx
->dst
;
837 tc
->tc_proto
= saidx
->proto
;
839 /* Crypto operation descriptor. */
840 crp
->crp_ilen
= m
->m_pkthdr
.len
; /* Total input length. */
841 crp
->crp_flags
= CRYPTO_F_IMBUF
;
842 crp
->crp_buf
= (caddr_t
) m
;
843 crp
->crp_callback
= esp_output_cb
;
844 crp
->crp_opaque
= (caddr_t
) tc
;
845 crp
->crp_sid
= sav
->tdb_cryptoid
;
848 /* Authentication descriptor. */
849 crda
->crd_skip
= skip
;
850 crda
->crd_len
= m
->m_pkthdr
.len
- (skip
+ alen
);
851 crda
->crd_inject
= m
->m_pkthdr
.len
- alen
;
853 /* Authentication operation. */
854 crda
->crd_alg
= esph
->type
;
855 crda
->crd_key
= _KEYBUF(sav
->key_auth
);
856 crda
->crd_klen
= _KEYBITS(sav
->key_auth
);
859 return crypto_dispatch(crp
);
867 * ESP output callback from the crypto driver.
870 esp_output_cb(struct cryptop
*crp
)
872 struct tdb_crypto
*tc
;
873 struct ipsecrequest
*isr
;
874 struct secasvar
*sav
;
878 tc
= (struct tdb_crypto
*) crp
->crp_opaque
;
879 KASSERT(tc
!= NULL
, ("esp_output_cb: null opaque data area!"));
880 m
= (struct mbuf
*) crp
->crp_buf
;
885 sav
= KEY_ALLOCSA(&tc
->tc_dst
, tc
->tc_proto
, tc
->tc_spi
);
887 espstat
.esps_notdb
++;
888 DPRINTF(("esp_output_cb: SA expired while in crypto "
889 "(SA %s/%08lx proto %u)\n", ipsec_address(&tc
->tc_dst
),
890 (u_long
) ntohl(tc
->tc_spi
), tc
->tc_proto
));
891 error
= ENOBUFS
; /*XXX*/
894 KASSERT(isr
->sav
== sav
,
895 ("esp_output_cb: SA changed was %p now %p\n", isr
->sav
, sav
));
897 /* Check for crypto errors. */
898 if (crp
->crp_etype
) {
899 /* Reset session ID. */
900 if (sav
->tdb_cryptoid
!= 0)
901 sav
->tdb_cryptoid
= crp
->crp_sid
;
903 if (crp
->crp_etype
== EAGAIN
) {
906 return crypto_dispatch(crp
);
909 espstat
.esps_noxform
++;
910 DPRINTF(("esp_output_cb: crypto error %d\n", crp
->crp_etype
));
911 error
= crp
->crp_etype
;
915 /* Shouldn't happen... */
917 espstat
.esps_crypto
++;
918 DPRINTF(("esp_output_cb: bogus returned buffer from crypto\n"));
922 espstat
.esps_hist
[sav
->alg_enc
]++;
923 if (sav
->tdb_authalgxform
!= NULL
)
924 ahstat
.ahs_hist
[sav
->alg_auth
]++;
926 /* Release crypto descriptors. */
930 /* NB: m is reclaimed by ipsec_process_done. */
931 err
= ipsec_process_done(m
, isr
);
946 static struct xformsw esp_xformsw
= {
947 XF_ESP
, XFT_CONF
|XFT_AUTH
, "IPsec ESP",
948 esp_init
, esp_zeroize
, esp_input
,
955 #define MAXIV(xform) \
956 if (xform.blocksize > esp_max_ivlen) \
957 esp_max_ivlen = xform.blocksize \
960 MAXIV(enc_xform_des
); /* SADB_EALG_DESCBC */
961 MAXIV(enc_xform_3des
); /* SADB_EALG_3DESCBC */
962 MAXIV(enc_xform_rijndael128
); /* SADB_X_EALG_AES */
963 MAXIV(enc_xform_blf
); /* SADB_X_EALG_BLOWFISHCBC */
964 MAXIV(enc_xform_cast5
); /* SADB_X_EALG_CAST128CBC */
965 MAXIV(enc_xform_skipjack
); /* SADB_X_EALG_SKIPJACK */
966 MAXIV(enc_xform_null
); /* SADB_EALG_NULL */
968 xform_register(&esp_xformsw
);
971 SYSINIT(esp_xform_init
, SI_SUB_DRIVERS
, SI_ORDER_FIRST
, esp_attach
, NULL
);