FreeBSD/sys/netipsec/xform_esp.c
/*
 * ESP output callback from the crypto driver.
 */
ESP output callback from the crypto driver.
ESP output callback from the crypto driver .
static int
esp_output_cb(struct cryptop *crp)
{
	char buf[INET6_ADDRSTRLEN];
	struct tdb_crypto *tc;
	struct ipsecrequest *isr;
	struct secasvar *sav;
	struct mbuf *m;
	int error;
	tc = (struct tdb_crypto *) crp->crp_opaque;
	IPSEC_ASSERT(tc != NULL, ("null opaque data area!"));
	m = (struct mbuf *) crp->crp_buf;
	isr = tc->tc_isr;
	IPSEC_ASSERT(isr->sp != NULL, ("NULL isr->sp"));
	IPSECREQUEST_LOCK(isr);
	sav = tc->tc_sav;
	if (sav != isr->sav) {
		ESPSTAT_INC(esps_notdb);
		DPRINTF(("%s: SA gone during crypto (SA %s/%08lx proto %u)\n",
		    __func__, ipsec_address(&tc->tc_dst, buf, sizeof(buf)),
		    (u_long) ntohl(tc->tc_spi), tc->tc_proto));
		error = ENOBUFS;		
		goto bad;
	}
	if (crp->crp_etype) {
		if (sav->tdb_cryptoid != 0)
			sav->tdb_cryptoid = crp->crp_sid;
		if (crp->crp_etype == EAGAIN) {
			IPSECREQUEST_UNLOCK(isr);
			return (crypto_dispatch(crp));
		}
		ESPSTAT_INC(esps_noxform);
		DPRINTF(("%s: crypto error %d\n", __func__, crp->crp_etype));
		error = crp->crp_etype;
		goto bad;
	}
	if (m == NULL) {
		ESPSTAT_INC(esps_crypto);
		DPRINTF(("%s: bogus returned buffer from crypto\n", __func__));
		error = EINVAL;
		goto bad;
	}
	ESPSTAT_INC(esps_hist[sav->alg_enc]);
	if (sav->tdb_authalgxform != NULL)
		AHSTAT_INC(ahs_hist[sav->alg_auth]);
	free(tc, M_XDATA);
	crypto_freereq(crp);
#ifdef REGRESSION
	if (V_ipsec_integrity) {
		static unsigned char ipseczeroes[AH_HMAC_MAXHASHLEN];
		struct auth_hash *esph;
		esph = sav->tdb_authalgxform;
		if (esph !=  NULL) {
			int alen;
			alen = xform_ah_authsize(esph);
			m_copyback(m, m->m_pkthdr.len - alen,
			    alen, ipseczeroes);
		}
	}
#endif
	error = ipsec_process_done(m, isr);
	KEY_FREESAV(&sav);
	IPSECREQUEST_UNLOCK(isr);
	KEY_FREESP(&isr->sp);
	return (error);
bad:
	if (sav)
		KEY_FREESAV(&sav);
	IPSECREQUEST_UNLOCK(isr);
	KEY_FREESP(&isr->sp);
	if (m)
		m_freem(m);
	free(tc, M_XDATA);
	crypto_freereq(crp);
	return (error);
}
static int esp_output_cb ( struct cryptop * crp ) { char buf [ INET6_ADDRSTRLEN ] ; struct tdb_crypto * tc ; struct ipsecrequest * isr ; struct secasvar * sav ; struct mbuf * m ; int error ; tc = ( struct tdb_crypto * ) crp -> crp_opaque ; IPSEC_ASSERT ( tc != NULL , ( " " ) ) ; m = ( struct mbuf * ) crp -> crp_buf ; isr = tc -> tc_isr ; IPSEC_ASSERT ( isr -> sp != NULL , ( " " ) ) ; IPSECREQUEST_LOCK ( isr ) ; sav = tc -> tc_sav ; if ( sav != isr -> sav ) { ESPSTAT_INC ( esps_notdb ) ; DPRINTF ( ( " \n " , __func__ , ipsec_address ( & tc -> tc_dst , buf , sizeof ( buf ) ) , ( u_long ) ntohl ( tc -> tc_spi ) , tc -> tc_proto ) ) ; error = ENOBUFS ; goto bad ; } if ( crp -> crp_etype ) { if ( sav -> tdb_cryptoid != 0 ) sav -> tdb_cryptoid = crp -> crp_sid ; if ( crp -> crp_etype == EAGAIN ) { IPSECREQUEST_UNLOCK ( isr ) ; return ( crypto_dispatch ( crp ) ) ; } ESPSTAT_INC ( esps_noxform ) ; DPRINTF ( ( " \n " , __func__ , crp -> crp_etype ) ) ; error = crp -> crp_etype ; goto bad ; } if ( m == NULL ) { ESPSTAT_INC ( esps_crypto ) ; DPRINTF ( ( " \n " , __func__ ) ) ; error = EINVAL ; goto bad ; } ESPSTAT_INC ( esps_hist [ sav -> alg_enc ] ) ; if ( sav -> tdb_authalgxform != NULL ) AHSTAT_INC ( ahs_hist [ sav -> alg_auth ] ) ; free ( tc , M_XDATA ) ; crypto_freereq ( crp ) ; #ifdef REGRESSION if ( V_ipsec_integrity ) { static unsigned char ipseczeroes [ AH_HMAC_MAXHASHLEN ] ; struct auth_hash * esph ; esph = sav -> tdb_authalgxform ; if ( esph != NULL ) { int alen ; alen = xform_ah_authsize ( esph ) ; m_copyback ( m , m -> m_pkthdr . len - alen , alen , ipseczeroes ) ; } } #endif error = ipsec_process_done ( m , isr ) ; KEY_FREESAV ( & sav ) ; IPSECREQUEST_UNLOCK ( isr ) ; KEY_FREESP ( & isr -> sp ) ; return ( error ) ; bad : if ( sav ) KEY_FREESAV ( & sav ) ; IPSECREQUEST_UNLOCK ( isr ) ; KEY_FREESP ( & isr -> sp ) ; if ( m ) m_freem ( m ) ; free ( tc , M_XDATA ) ; crypto_freereq ( crp ) ; return ( error ) ; }
ESP output callback from the crypto driver.
ESP output callback from the crypto driver .
/* With the isr lock released, SA pointer may have changed. */ /*XXX*/ /* Check for crypto errors. */ /* Reset session ID. */ /* Shouldn't happen... */ /* Release crypto descriptors. */ /* Emulate man-in-the-middle attack when ipsec_integrity is TRUE. */ /*
		 * Corrupt HMAC if we want to test integrity verification of
		 * the other side.
		 */ /* NB: m is reclaimed by ipsec_process_done. */