Changeset View
Changeset View
Standalone View
Standalone View
head/sys/netipsec/xform_esp.c
Show First 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | |||||
#endif | #endif | ||||
#include <netipsec/key.h> | #include <netipsec/key.h> | ||||
#include <netipsec/key_debug.h> | #include <netipsec/key_debug.h> | ||||
#include <opencrypto/cryptodev.h> | #include <opencrypto/cryptodev.h> | ||||
#include <opencrypto/xform.h> | #include <opencrypto/xform.h> | ||||
#define SPI_SIZE 4 | |||||
VNET_DEFINE(int, esp_enable) = 1; | VNET_DEFINE(int, esp_enable) = 1; | ||||
VNET_DEFINE_STATIC(int, esp_ctr_compatibility) = 1; | VNET_DEFINE_STATIC(int, esp_ctr_compatibility) = 1; | ||||
#define V_esp_ctr_compatibility VNET(esp_ctr_compatibility) | #define V_esp_ctr_compatibility VNET(esp_ctr_compatibility) | ||||
VNET_PCPUSTAT_DEFINE(struct espstat, espstat); | VNET_PCPUSTAT_DEFINE(struct espstat, espstat); | ||||
VNET_PCPUSTAT_SYSINIT(espstat); | VNET_PCPUSTAT_SYSINIT(espstat); | ||||
#ifdef VIMAGE | #ifdef VIMAGE | ||||
VNET_PCPUSTAT_SYSUNINIT(espstat); | VNET_PCPUSTAT_SYSUNINIT(espstat); | ||||
▲ Show 20 Lines • Show All 123 Lines • ▼ Show 20 Lines | case AES_256_GMAC_KEY_LEN: | ||||
break; | break; | ||||
default: | default: | ||||
DPRINTF(("%s: invalid key length %u" | DPRINTF(("%s: invalid key length %u" | ||||
"for algorithm %s\n", __func__, | "for algorithm %s\n", __func__, | ||||
keylen, txform->name)); | keylen, txform->name)); | ||||
return EINVAL; | return EINVAL; | ||||
} | } | ||||
csp.csp_mode = CSP_MODE_AEAD; | csp.csp_mode = CSP_MODE_AEAD; | ||||
} else if (sav->alg_auth != 0) | if (sav->flags & SADB_X_SAFLAGS_ESN) | ||||
csp.csp_flags |= CSP_F_SEPARATE_AAD; | |||||
} else if (sav->alg_auth != 0) { | |||||
csp.csp_mode = CSP_MODE_ETA; | csp.csp_mode = CSP_MODE_ETA; | ||||
else | if (sav->flags & SADB_X_SAFLAGS_ESN) | ||||
csp.csp_flags |= CSP_F_ESN; | |||||
} else | |||||
csp.csp_mode = CSP_MODE_CIPHER; | csp.csp_mode = CSP_MODE_CIPHER; | ||||
/* Initialize crypto session. */ | /* Initialize crypto session. */ | ||||
csp.csp_cipher_alg = sav->tdb_encalgxform->type; | csp.csp_cipher_alg = sav->tdb_encalgxform->type; | ||||
if (csp.csp_cipher_alg != CRYPTO_NULL_CBC) { | if (csp.csp_cipher_alg != CRYPTO_NULL_CBC) { | ||||
csp.csp_cipher_key = sav->key_enc->key_data; | csp.csp_cipher_key = sav->key_enc->key_data; | ||||
csp.csp_cipher_klen = _KEYBITS(sav->key_enc) / 8 - | csp.csp_cipher_klen = _KEYBITS(sav->key_enc) / 8 - | ||||
SAV_ISCTRORGCM(sav) * 4; | SAV_ISCTRORGCM(sav) * 4; | ||||
Show All 25 Lines | esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) | ||||
const struct enc_xform *espx; | const struct enc_xform *espx; | ||||
struct xform_data *xd; | struct xform_data *xd; | ||||
struct cryptop *crp; | struct cryptop *crp; | ||||
struct newesp *esp; | struct newesp *esp; | ||||
uint8_t *ivp; | uint8_t *ivp; | ||||
crypto_session_t cryptoid; | crypto_session_t cryptoid; | ||||
int alen, error, hlen, plen; | int alen, error, hlen, plen; | ||||
uint32_t seqh; | uint32_t seqh; | ||||
const struct crypto_session_params *csp; | |||||
IPSEC_ASSERT(sav != NULL, ("null SA")); | IPSEC_ASSERT(sav != NULL, ("null SA")); | ||||
IPSEC_ASSERT(sav->tdb_encalgxform != NULL, ("null encoding xform")); | IPSEC_ASSERT(sav->tdb_encalgxform != NULL, ("null encoding xform")); | ||||
error = EINVAL; | error = EINVAL; | ||||
/* Valid IP Packet length ? */ | /* Valid IP Packet length ? */ | ||||
if ( (skip&3) || (m->m_pkthdr.len&3) ){ | if ( (skip&3) || (m->m_pkthdr.len&3) ){ | ||||
DPRINTF(("%s: misaligned packet, skip %u pkt len %u", | DPRINTF(("%s: misaligned packet, skip %u pkt len %u", | ||||
▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | if (esph != NULL && sav->replay != NULL && sav->replay->wsize != 0) { | ||||
if (ipsec_chkreplay(ntohl(esp->esp_seq), &seqh, sav) == 0) { | if (ipsec_chkreplay(ntohl(esp->esp_seq), &seqh, sav) == 0) { | ||||
SECASVAR_UNLOCK(sav); | SECASVAR_UNLOCK(sav); | ||||
DPRINTF(("%s: packet replay check for %s\n", __func__, | DPRINTF(("%s: packet replay check for %s\n", __func__, | ||||
ipsec_sa2str(sav, buf, sizeof(buf)))); | ipsec_sa2str(sav, buf, sizeof(buf)))); | ||||
ESPSTAT_INC(esps_replay); | ESPSTAT_INC(esps_replay); | ||||
error = EACCES; | error = EACCES; | ||||
goto bad; | goto bad; | ||||
} | } | ||||
seqh = htonl(seqh); | |||||
} | } | ||||
cryptoid = sav->tdb_cryptoid; | cryptoid = sav->tdb_cryptoid; | ||||
SECASVAR_UNLOCK(sav); | SECASVAR_UNLOCK(sav); | ||||
/* Update the counters */ | /* Update the counters */ | ||||
ESPSTAT_ADD(esps_ibytes, m->m_pkthdr.len - (skip + hlen + alen)); | ESPSTAT_ADD(esps_ibytes, m->m_pkthdr.len - (skip + hlen + alen)); | ||||
/* Get crypto descriptors */ | /* Get crypto descriptors */ | ||||
crp = crypto_getreq(cryptoid, M_NOWAIT); | crp = crypto_getreq(cryptoid, M_NOWAIT); | ||||
if (crp == NULL) { | if (crp == NULL) { | ||||
DPRINTF(("%s: failed to acquire crypto descriptors\n", | DPRINTF(("%s: failed to acquire crypto descriptors\n", | ||||
__func__)); | __func__)); | ||||
ESPSTAT_INC(esps_crypto); | ESPSTAT_INC(esps_crypto); | ||||
error = ENOBUFS; | error = ENOBUFS; | ||||
goto bad; | goto bad; | ||||
} | } | ||||
/* Get IPsec-specific opaque pointer */ | /* Get IPsec-specific opaque pointer */ | ||||
xd = malloc(sizeof(*xd), M_XDATA, M_NOWAIT | M_ZERO); | xd = malloc(sizeof(*xd), M_XDATA, M_NOWAIT | M_ZERO); | ||||
if (xd == NULL) { | if (xd == NULL) { | ||||
DPRINTF(("%s: failed to allocate xform_data\n", __func__)); | DPRINTF(("%s: failed to allocate xform_data\n", __func__)); | ||||
ESPSTAT_INC(esps_crypto); | goto xd_fail; | ||||
crypto_freereq(crp); | |||||
error = ENOBUFS; | |||||
goto bad; | |||||
} | } | ||||
if (esph != NULL) { | if (esph != NULL) { | ||||
crp->crp_op = CRYPTO_OP_VERIFY_DIGEST; | crp->crp_op = CRYPTO_OP_VERIFY_DIGEST; | ||||
crp->crp_aad_start = skip; | |||||
if (SAV_ISGCM(sav)) | if (SAV_ISGCM(sav)) | ||||
crp->crp_aad_length = 8; /* RFC4106 5, SPI + SN */ | crp->crp_aad_length = 8; /* RFC4106 5, SPI + SN */ | ||||
else | else | ||||
crp->crp_aad_length = hlen; | crp->crp_aad_length = hlen; | ||||
csp = crypto_get_params(crp->crp_session); | |||||
if ((csp->csp_flags & CSP_F_SEPARATE_AAD) && | |||||
(sav->replay != NULL) && (sav->replay->wsize != 0)) { | |||||
int aad_skip; | |||||
crp->crp_aad_length += sizeof(seqh); | |||||
crp->crp_aad = malloc(crp->crp_aad_length, M_XDATA, M_NOWAIT); | |||||
if (crp->crp_aad == NULL) { | |||||
DPRINTF(("%s: failed to allocate xform_data\n", | |||||
__func__)); | |||||
goto crp_aad_fail; | |||||
} | |||||
/* SPI */ | |||||
m_copydata(m, skip, SPI_SIZE, crp->crp_aad); | |||||
aad_skip = SPI_SIZE; | |||||
/* ESN */ | |||||
bcopy(&seqh, (char *)crp->crp_aad + aad_skip, sizeof(seqh)); | |||||
aad_skip += sizeof(seqh); | |||||
/* Rest of aad */ | |||||
if (crp->crp_aad_length - aad_skip > 0) | |||||
m_copydata(m, skip + SPI_SIZE, | |||||
crp->crp_aad_length - aad_skip, | |||||
(char *)crp->crp_aad + aad_skip); | |||||
} else | |||||
crp->crp_aad_start = skip; | |||||
if (csp->csp_flags & CSP_F_ESN && | |||||
sav->replay != NULL && sav->replay->wsize != 0) | |||||
memcpy(crp->crp_esn, &seqh, sizeof(seqh)); | |||||
crp->crp_digest_start = m->m_pkthdr.len - alen; | crp->crp_digest_start = m->m_pkthdr.len - alen; | ||||
} | } | ||||
/* Crypto operation descriptor */ | /* Crypto operation descriptor */ | ||||
crp->crp_flags = CRYPTO_F_CBIFSYNC; | crp->crp_flags = CRYPTO_F_CBIFSYNC; | ||||
if (V_async_crypto) | if (V_async_crypto) | ||||
crp->crp_flags |= CRYPTO_F_ASYNC | CRYPTO_F_ASYNC_KEEPORDER; | crp->crp_flags |= CRYPTO_F_ASYNC | CRYPTO_F_ASYNC_KEEPORDER; | ||||
crypto_use_mbuf(crp, m); | crypto_use_mbuf(crp, m); | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | if (SAV_ISCTRORGCM(sav)) { | ||||
if (SAV_ISCTR(sav)) { | if (SAV_ISCTR(sav)) { | ||||
be32enc(&ivp[sav->ivlen + 4], 1); | be32enc(&ivp[sav->ivlen + 4], 1); | ||||
} | } | ||||
crp->crp_flags |= CRYPTO_F_IV_SEPARATE; | crp->crp_flags |= CRYPTO_F_IV_SEPARATE; | ||||
} else if (sav->ivlen != 0) | } else if (sav->ivlen != 0) | ||||
crp->crp_iv_start = skip + hlen - sav->ivlen; | crp->crp_iv_start = skip + hlen - sav->ivlen; | ||||
return (crypto_dispatch(crp)); | return (crypto_dispatch(crp)); | ||||
crp_aad_fail: | |||||
free(xd, M_XDATA); | |||||
xd_fail: | |||||
crypto_freereq(crp); | |||||
ESPSTAT_INC(esps_crypto); | |||||
error = ENOBUFS; | |||||
bad: | bad: | ||||
m_freem(m); | m_freem(m); | ||||
key_freesav(&sav); | key_freesav(&sav); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* ESP input callback from the crypto driver. | * ESP input callback from the crypto driver. | ||||
▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | if (esph != NULL) { | ||||
} | } | ||||
m->m_flags |= M_AUTHIPDGM; | m->m_flags |= M_AUTHIPDGM; | ||||
/* Remove trailing authenticator */ | /* Remove trailing authenticator */ | ||||
m_adj(m, -alen); | m_adj(m, -alen); | ||||
} | } | ||||
/* Release the crypto descriptors */ | /* Release the crypto descriptors */ | ||||
free(xd, M_XDATA), xd = NULL; | free(xd, M_XDATA), xd = NULL; | ||||
free(crp->crp_aad, M_XDATA), crp->crp_aad = NULL; | |||||
crypto_freereq(crp), crp = NULL; | crypto_freereq(crp), crp = NULL; | ||||
/* | /* | ||||
* Packet is now decrypted. | * Packet is now decrypted. | ||||
*/ | */ | ||||
m->m_flags |= M_DECRYPTED; | m->m_flags |= M_DECRYPTED; | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | |||||
bad: | bad: | ||||
CURVNET_RESTORE(); | CURVNET_RESTORE(); | ||||
if (sav != NULL) | if (sav != NULL) | ||||
key_freesav(&sav); | key_freesav(&sav); | ||||
if (m != NULL) | if (m != NULL) | ||||
m_freem(m); | m_freem(m); | ||||
if (xd != NULL) | if (xd != NULL) | ||||
free(xd, M_XDATA); | free(xd, M_XDATA); | ||||
if (crp != NULL) | if (crp != NULL) { | ||||
free(crp->crp_aad, M_XDATA); | |||||
crypto_freereq(crp); | crypto_freereq(crp); | ||||
} | |||||
return error; | return error; | ||||
} | } | ||||
/* | /* | ||||
* ESP output routine, called by ipsec[46]_perform_request(). | * ESP output routine, called by ipsec[46]_perform_request(). | ||||
*/ | */ | ||||
static int | static int | ||||
esp_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav, | esp_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav, | ||||
u_int idx, int skip, int protoff) | u_int idx, int skip, int protoff) | ||||
{ | { | ||||
IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]); | IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]); | ||||
struct cryptop *crp; | struct cryptop *crp; | ||||
const struct auth_hash *esph; | const struct auth_hash *esph; | ||||
const struct enc_xform *espx; | const struct enc_xform *espx; | ||||
struct mbuf *mo = NULL; | struct mbuf *mo = NULL; | ||||
struct xform_data *xd; | struct xform_data *xd; | ||||
struct secasindex *saidx; | struct secasindex *saidx; | ||||
unsigned char *pad; | unsigned char *pad; | ||||
uint8_t *ivp; | uint8_t *ivp; | ||||
uint64_t cntr; | uint64_t cntr; | ||||
crypto_session_t cryptoid; | crypto_session_t cryptoid; | ||||
int hlen, rlen, padding, blks, alen, i, roff; | int hlen, rlen, padding, blks, alen, i, roff; | ||||
int error, maxpacketsize; | int error, maxpacketsize; | ||||
uint8_t prot; | uint8_t prot; | ||||
uint32_t seqh; | |||||
const struct crypto_session_params *csp; | |||||
IPSEC_ASSERT(sav != NULL, ("null SA")); | IPSEC_ASSERT(sav != NULL, ("null SA")); | ||||
esph = sav->tdb_authalgxform; | esph = sav->tdb_authalgxform; | ||||
espx = sav->tdb_encalgxform; | espx = sav->tdb_encalgxform; | ||||
IPSEC_ASSERT(espx != NULL, ("null encoding xform")); | IPSEC_ASSERT(espx != NULL, ("null encoding xform")); | ||||
if (sav->flags & SADB_X_EXT_OLD) | if (sav->flags & SADB_X_EXT_OLD) | ||||
hlen = sizeof (struct esp) + sav->ivlen; | hlen = sizeof (struct esp) + sav->ivlen; | ||||
▲ Show 20 Lines • Show All 90 Lines • ▼ Show 20 Lines | #ifdef REGRESSION | ||||
/* Emulate replay attack when ipsec_replay is TRUE. */ | /* Emulate replay attack when ipsec_replay is TRUE. */ | ||||
if (!V_ipsec_replay) | if (!V_ipsec_replay) | ||||
#endif | #endif | ||||
sav->replay->count++; | sav->replay->count++; | ||||
replay = htonl((uint32_t)sav->replay->count); | replay = htonl((uint32_t)sav->replay->count); | ||||
bcopy((caddr_t) &replay, mtod(mo, caddr_t) + roff + | bcopy((caddr_t) &replay, mtod(mo, caddr_t) + roff + | ||||
sizeof(uint32_t), sizeof(uint32_t)); | sizeof(uint32_t), sizeof(uint32_t)); | ||||
seqh = htonl((uint32_t)(sav->replay->count >> IPSEC_SEQH_SHIFT)); | |||||
} | } | ||||
cryptoid = sav->tdb_cryptoid; | cryptoid = sav->tdb_cryptoid; | ||||
if (SAV_ISCTRORGCM(sav)) | if (SAV_ISCTRORGCM(sav)) | ||||
cntr = sav->cntr++; | cntr = sav->cntr++; | ||||
SECASVAR_UNLOCK(sav); | SECASVAR_UNLOCK(sav); | ||||
/* | /* | ||||
* Add padding -- better to do it ourselves than use the crypto engine, | * Add padding -- better to do it ourselves than use the crypto engine, | ||||
Show All 40 Lines | if (crp == NULL) { | ||||
DPRINTF(("%s: failed to acquire crypto descriptor\n", | DPRINTF(("%s: failed to acquire crypto descriptor\n", | ||||
__func__)); | __func__)); | ||||
ESPSTAT_INC(esps_crypto); | ESPSTAT_INC(esps_crypto); | ||||
error = ENOBUFS; | error = ENOBUFS; | ||||
goto bad; | goto bad; | ||||
} | } | ||||
/* IPsec-specific opaque crypto info. */ | /* IPsec-specific opaque crypto info. */ | ||||
xd = malloc(sizeof(struct xform_data), M_XDATA, M_NOWAIT | M_ZERO); | xd = malloc(sizeof(struct xform_data), M_XDATA, M_NOWAIT | M_ZERO); | ||||
if (xd == NULL) { | if (xd == NULL) { | ||||
crypto_freereq(crp); | |||||
DPRINTF(("%s: failed to allocate xform_data\n", __func__)); | DPRINTF(("%s: failed to allocate xform_data\n", __func__)); | ||||
ESPSTAT_INC(esps_crypto); | goto xd_fail; | ||||
error = ENOBUFS; | |||||
goto bad; | |||||
} | } | ||||
/* Encryption descriptor. */ | /* Encryption descriptor. */ | ||||
crp->crp_payload_start = skip + hlen; | crp->crp_payload_start = skip + hlen; | ||||
crp->crp_payload_length = m->m_pkthdr.len - (skip + hlen + alen); | crp->crp_payload_length = m->m_pkthdr.len - (skip + hlen + alen); | ||||
crp->crp_op = CRYPTO_OP_ENCRYPT; | crp->crp_op = CRYPTO_OP_ENCRYPT; | ||||
/* Generate cipher and ESP IVs. */ | /* Generate cipher and ESP IVs. */ | ||||
Show All 31 Lines | if (V_async_crypto) | ||||
crp->crp_flags |= CRYPTO_F_ASYNC | CRYPTO_F_ASYNC_KEEPORDER; | crp->crp_flags |= CRYPTO_F_ASYNC | CRYPTO_F_ASYNC_KEEPORDER; | ||||
crypto_use_mbuf(crp, m); | crypto_use_mbuf(crp, m); | ||||
crp->crp_callback = esp_output_cb; | crp->crp_callback = esp_output_cb; | ||||
crp->crp_opaque = xd; | crp->crp_opaque = xd; | ||||
if (esph) { | if (esph) { | ||||
/* Authentication descriptor. */ | /* Authentication descriptor. */ | ||||
crp->crp_op |= CRYPTO_OP_COMPUTE_DIGEST; | crp->crp_op |= CRYPTO_OP_COMPUTE_DIGEST; | ||||
crp->crp_aad_start = skip; | |||||
if (SAV_ISGCM(sav)) | if (SAV_ISGCM(sav)) | ||||
crp->crp_aad_length = 8; /* RFC4106 5, SPI + SN */ | crp->crp_aad_length = 8; /* RFC4106 5, SPI + SN */ | ||||
else | else | ||||
crp->crp_aad_length = hlen; | crp->crp_aad_length = hlen; | ||||
csp = crypto_get_params(crp->crp_session); | |||||
if (csp->csp_flags & CSP_F_SEPARATE_AAD && | |||||
sav->replay != NULL) { | |||||
int aad_skip; | |||||
crp->crp_aad_length += sizeof(seqh); | |||||
crp->crp_aad = malloc(crp->crp_aad_length, M_XDATA, M_NOWAIT); | |||||
if (crp->crp_aad == NULL) { | |||||
DPRINTF(("%s: failed to allocate xform_data\n", | |||||
__func__)); | |||||
goto crp_aad_fail; | |||||
} | |||||
/* SPI */ | |||||
m_copydata(m, skip, SPI_SIZE, crp->crp_aad); | |||||
aad_skip = SPI_SIZE; | |||||
/* ESN */ | |||||
bcopy(&seqh, (char *)crp->crp_aad + aad_skip, sizeof(seqh)); | |||||
aad_skip += sizeof(seqh); | |||||
/* Rest of aad */ | |||||
if (crp->crp_aad_length - aad_skip > 0) | |||||
m_copydata(m, skip + SPI_SIZE, | |||||
crp->crp_aad_length - aad_skip, | |||||
(char *)crp->crp_aad + aad_skip); | |||||
} else | |||||
crp->crp_aad_start = skip; | |||||
if (csp->csp_flags & CSP_F_ESN && sav->replay != NULL) | |||||
memcpy(crp->crp_esn, &seqh, sizeof(seqh)); | |||||
crp->crp_digest_start = m->m_pkthdr.len - alen; | crp->crp_digest_start = m->m_pkthdr.len - alen; | ||||
} | } | ||||
return crypto_dispatch(crp); | return crypto_dispatch(crp); | ||||
crp_aad_fail: | |||||
free(xd, M_XDATA); | |||||
xd_fail: | |||||
crypto_freereq(crp); | |||||
ESPSTAT_INC(esps_crypto); | |||||
error = ENOBUFS; | |||||
bad: | bad: | ||||
if (m) | if (m) | ||||
m_freem(m); | m_freem(m); | ||||
key_freesav(&sav); | key_freesav(&sav); | ||||
key_freesp(&sp); | key_freesp(&sp); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
Show All 38 Lines | esp_output_cb(struct cryptop *crp) | ||||
/* Shouldn't happen... */ | /* Shouldn't happen... */ | ||||
if (m == NULL) { | if (m == NULL) { | ||||
ESPSTAT_INC(esps_crypto); | ESPSTAT_INC(esps_crypto); | ||||
DPRINTF(("%s: bogus returned buffer from crypto\n", __func__)); | DPRINTF(("%s: bogus returned buffer from crypto\n", __func__)); | ||||
error = EINVAL; | error = EINVAL; | ||||
goto bad; | goto bad; | ||||
} | } | ||||
free(xd, M_XDATA); | free(xd, M_XDATA); | ||||
free(crp->crp_aad, M_XDATA); | |||||
crypto_freereq(crp); | crypto_freereq(crp); | ||||
ESPSTAT_INC(esps_hist[sav->alg_enc]); | ESPSTAT_INC(esps_hist[sav->alg_enc]); | ||||
if (sav->tdb_authalgxform != NULL) | if (sav->tdb_authalgxform != NULL) | ||||
AHSTAT_INC(ahs_hist[sav->alg_auth]); | AHSTAT_INC(ahs_hist[sav->alg_auth]); | ||||
#ifdef REGRESSION | #ifdef REGRESSION | ||||
/* Emulate man-in-the-middle attack when ipsec_integrity is TRUE. */ | /* Emulate man-in-the-middle attack when ipsec_integrity is TRUE. */ | ||||
if (V_ipsec_integrity) { | if (V_ipsec_integrity) { | ||||
Show All 17 Lines | #endif | ||||
/* NB: m is reclaimed by ipsec_process_done. */ | /* NB: m is reclaimed by ipsec_process_done. */ | ||||
error = ipsec_process_done(m, sp, sav, idx); | error = ipsec_process_done(m, sp, sav, idx); | ||||
CURVNET_RESTORE(); | CURVNET_RESTORE(); | ||||
return (error); | return (error); | ||||
bad: | bad: | ||||
CURVNET_RESTORE(); | CURVNET_RESTORE(); | ||||
free(xd, M_XDATA); | free(xd, M_XDATA); | ||||
free(crp->crp_aad, M_XDATA); | |||||
crypto_freereq(crp); | crypto_freereq(crp); | ||||
key_freesav(&sav); | key_freesav(&sav); | ||||
key_freesp(&sp); | key_freesp(&sp); | ||||
return (error); | return (error); | ||||
} | } | ||||
static struct xformsw esp_xformsw = { | static struct xformsw esp_xformsw = { | ||||
.xf_type = XF_ESP, | .xf_type = XF_ESP, | ||||
Show All 11 Lines |