Changeset View
Changeset View
Standalone View
Standalone View
sys/netipsec/xform_esp.c
Show First 20 Lines • Show All 209 Lines • ▼ Show 20 Lines | 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) | } else if (sav->alg_auth != 0) | ||||||||
csp.csp_mode = CSP_MODE_ETA; | csp.csp_mode = CSP_MODE_ETA; | ||||||||
else | else | ||||||||
gnn: Push else up to } else and please check indenting in this section. | |||||||||
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 20 Lines • Show All 124 Lines • ▼ Show 20 Lines | esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) | ||||||||
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); | ESPSTAT_INC(esps_crypto); | ||||||||
crypto_freereq(crp); | crypto_freereq(crp); | ||||||||
error = ENOBUFS; | error = ENOBUFS; | ||||||||
goto bad; | goto bad; | ||||||||
} | } | ||||||||
crp->crp_flags = CRYPTO_F_CBIFSYNC; | |||||||||
Done Inline ActionsMoving this is fine but looks like a no-op? jhb: Moving this is fine but looks like a no-op? | |||||||||
Done Inline ActionsThis was leftover from previous approach - I've undo this change. Thank you. jaz_semihalf.com: This was leftover from previous approach - I've undo this change. Thank you. | |||||||||
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; | 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; | ||||||||
crp->crp_digest_start = m->m_pkthdr.len - alen; | crp->crp_digest_start = m->m_pkthdr.len - alen; | ||||||||
if (sav->flags & SADB_X_SAFLAGS_ESN && | |||||||||
Done Inline ActionsAdd braces to make this clearer as to which operation goes where. gnn: Add braces to make this clearer as to which operation goes where. | |||||||||
sav->replay != NULL && sav->replay->wsize != 0) { | |||||||||
seqh = htonl(seqh); | |||||||||
Done Inline ActionsConvert magic number (4) to a #define or const. gnn: Convert magic number (4) to a #define or const. | |||||||||
memcpy(crp->crp_esn, &seqh, 4); | |||||||||
crp->crp_flags |= CRYPTO_F_ESN; | |||||||||
} | } | ||||||||
} | |||||||||
/* Crypto operation descriptor */ | /* Crypto operation descriptor */ | ||||||||
crp->crp_ilen = m->m_pkthdr.len; /* Total input length */ | crp->crp_ilen = m->m_pkthdr.len; /* Total input length */ | ||||||||
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; | ||||||||
Not Done Inline ActionsMinor nit: blank line before here. jhb: Minor nit: blank line before here. | |||||||||
crp->crp_mbuf = m; | crp->crp_mbuf = m; | ||||||||
crp->crp_buf_type = CRYPTO_BUF_MBUF; | crp->crp_buf_type = CRYPTO_BUF_MBUF; | ||||||||
crp->crp_callback = esp_input_cb; | crp->crp_callback = esp_input_cb; | ||||||||
crp->crp_opaque = xd; | crp->crp_opaque = xd; | ||||||||
/* These are passed as-is to the callback */ | /* These are passed as-is to the callback */ | ||||||||
xd->sav = sav; | xd->sav = sav; | ||||||||
xd->protoff = protoff; | xd->protoff = protoff; | ||||||||
▲ Show 20 Lines • Show All 229 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) | ||||||||
Done Inline Actions
Alternatively, you could move the free(crp->crp_aad, M_XDATA) under the existing if (crp != NULL) below since free(NULL, ..) is defined to be a nop. jhb: Alternatively, you could move the `free(crp->crp_aad, M_XDATA)` under the existing `if (crp !=… | |||||||||
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; | |||||||||
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 85 Lines • ▼ Show 20 Lines | #ifdef REGRESSION | ||||||||
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)); | ||||||||
} | } | ||||||||
cryptoid = sav->tdb_cryptoid; | cryptoid = sav->tdb_cryptoid; | ||||||||
Done Inline Actions#dedfine for magic number gnn: #dedfine for magic number | |||||||||
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, | ||||||||
* although if/when we support compression, we'd have to do that. | * although if/when we support compression, we'd have to do that. | ||||||||
*/ | */ | ||||||||
▲ Show 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | 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; | 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; | ||||||||
crp->crp_digest_start = m->m_pkthdr.len - alen; | crp->crp_digest_start = m->m_pkthdr.len - alen; | ||||||||
if (sav->flags & SADB_X_SAFLAGS_ESN && sav->replay != NULL) { | |||||||||
seqh = htonl((uint32_t)(sav->replay->count >> 32)); | |||||||||
memcpy(crp->crp_esn, &seqh, 4); | |||||||||
crp->crp_flags |= CRYPTO_F_ESN; | |||||||||
} | |||||||||
} | } | ||||||||
return crypto_dispatch(crp); | return crypto_dispatch(crp); | ||||||||
bad: | bad: | ||||||||
if (m) | if (m) | ||||||||
m_freem(m); | m_freem(m); | ||||||||
key_freesav(&sav); | key_freesav(&sav); | ||||||||
Not Done Inline ActionsHere as well. jhb: Here as well. | |||||||||
key_freesp(&sp); | key_freesp(&sp); | ||||||||
return (error); | return (error); | ||||||||
} | } | ||||||||
/* | /* | ||||||||
* ESP output callback from the crypto driver. | * ESP output callback from the crypto driver. | ||||||||
*/ | */ | ||||||||
static int | static int | ||||||||
esp_output_cb(struct cryptop *crp) | esp_output_cb(struct cryptop *crp) | ||||||||
Show All 34 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); | ||||||||
crypto_freereq(crp); | crypto_freereq(crp); | ||||||||
Done Inline ActionsAs below, you can just call free() unconditionally. There is also no need to clear crp_aad. jhb: As below, you can just call free() unconditionally. There is also no need to clear crp_aad. | |||||||||
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) { | ||||||||
static unsigned char ipseczeroes[AH_HMAC_MAXHASHLEN]; | static unsigned char ipseczeroes[AH_HMAC_MAXHASHLEN]; | ||||||||
Show All 16 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); | ||||||||
crypto_freereq(crp); | crypto_freereq(crp); | ||||||||
Done Inline ActionsThis can just be unconditional like the rest of this block since free(NULL) is ok. jhb: This can just be unconditional like the rest of this block since free(NULL) is ok. | |||||||||
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, | ||||||||
.xf_name = "IPsec ESP", | .xf_name = "IPsec ESP", | ||||||||
Show All 10 Lines |
Push else up to } else and please check indenting in this section.