diff options
Diffstat (limited to 'sys/netinet/ip_esp_new.c')
-rw-r--r-- | sys/netinet/ip_esp_new.c | 787 |
1 files changed, 294 insertions, 493 deletions
diff --git a/sys/netinet/ip_esp_new.c b/sys/netinet/ip_esp_new.c index 5a45bd97e76..26026302756 100644 --- a/sys/netinet/ip_esp_new.c +++ b/sys/netinet/ip_esp_new.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_esp_new.c,v 1.33 1999/02/17 20:39:17 deraadt Exp $ */ +/* $OpenBSD: ip_esp_new.c,v 1.34 1999/02/24 22:33:02 angelos Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), @@ -63,12 +63,11 @@ #include <sys/socketvar.h> #include <net/raw_cb.h> -#include <net/encap.h> #include <netinet/ip_icmp.h> #include <netinet/ip_ipsp.h> #include <netinet/ip_esp.h> -#include <netinet/ip_ah.h> +#include <net/pfkeyv2.h> #ifdef ENCDEBUG #define DPRINTF(x) if (encdebug) printf x @@ -76,39 +75,36 @@ #define DPRINTF(x) #endif -extern void encap_sendnotify(int, struct tdb *, void *); extern void des_ecb3_encrypt(caddr_t, caddr_t, caddr_t, caddr_t, caddr_t, int); extern void des_ecb_encrypt(caddr_t, caddr_t, caddr_t, int); extern void des_set_key(caddr_t, caddr_t); -static void des1_encrypt(void *, u_int8_t *); -static void des3_encrypt(void *, u_int8_t *); -static void blf_encrypt(void *, u_int8_t *); -static void cast5_encrypt(void *, u_int8_t *); -static void skipjack_encrypt(void *, u_int8_t *); -static void des1_decrypt(void *, u_int8_t *); -static void des3_decrypt(void *, u_int8_t *); -static void blf_decrypt(void *, u_int8_t *); -static void cast5_decrypt(void *, u_int8_t *); -static void skipjack_decrypt(void *, u_int8_t *); - -struct esp_hash esp_new_hash[] = { - { ALG_AUTH_MD5, "HMAC-MD5-96", - AH_MD5_ALEN, +static void des1_encrypt(struct tdb *, u_int8_t *); +static void des3_encrypt(struct tdb *, u_int8_t *); +static void blf_encrypt(struct tdb *, u_int8_t *); +static void cast5_encrypt(struct tdb *, u_int8_t *); +static void des1_decrypt(struct tdb *, u_int8_t *); +static void des3_decrypt(struct tdb *, u_int8_t *); +static void blf_decrypt(struct tdb *, u_int8_t *); +static void cast5_decrypt(struct tdb *, u_int8_t *); + +struct auth_hash esp_new_hash[] = { + { SADB_AALG_MD5HMAC96, "HMAC-MD5-96", + MD5HMAC96_KEYSIZE, AH_MD5_ALEN, sizeof(MD5_CTX), (void (*) (void *)) MD5Init, (void (*) (void *, u_int8_t *, u_int16_t)) MD5Update, (void (*) (u_int8_t *, void *)) MD5Final }, - { ALG_AUTH_SHA1, "HMAC-SHA1-96", - AH_SHA1_ALEN, + { SADB_AALG_SHA1HMAC96, "HMAC-SHA1-96", + SHA1HMAC96_KEYSIZE, AH_SHA1_ALEN, sizeof(SHA1_CTX), (void (*) (void *)) SHA1Init, (void (*) (void *, u_int8_t *, u_int16_t)) SHA1Update, (void (*) (u_int8_t *, void *)) SHA1Final }, - { ALG_AUTH_RMD160, "HMAC-RIPEMD-160-96", - AH_RMD160_ALEN, + { SADB_AALG_X_RIPEMD160HMAC96, "HMAC-RIPEMD-160-96", + RIPEMD160HMAC96_KEYSIZE, AH_RMD160_ALEN, sizeof(RMD160_CTX), (void (*)(void *)) RMD160Init, (void (*)(void *, u_int8_t *, u_int16_t)) RMD160Update, @@ -116,358 +112,251 @@ struct esp_hash esp_new_hash[] = { } }; -struct esp_xform esp_new_xform[] = { - { ALG_ENC_DES, "Data Encryption Standard (DES)", +struct enc_xform esp_new_xform[] = { + { SADB_EALG_DESCBC, "Data Encryption Standard (DES)", ESP_DES_BLKS, ESP_DES_IVS, - 8, 8, 8 | 1, + 8, 8, 8, des1_encrypt, des1_decrypt }, - { ALG_ENC_3DES, "Triple DES (3DES)", + { SADB_EALG_3DESCBC, "Triple DES (3DES)", ESP_3DES_BLKS, ESP_3DES_IVS, - 24, 24, 8 | 1, + 24, 24, 8, des3_encrypt, des3_decrypt }, - { ALG_ENC_BLF, "Blowfish", + { SADB_EALG_X_BLF, "Blowfish", ESP_BLF_BLKS, ESP_BLF_IVS, - 5, BLF_MAXKEYLEN, 8 | 1, + 5, BLF_MAXKEYLEN, 8, blf_encrypt, blf_decrypt }, - { ALG_ENC_CAST, "CAST", + { SADB_EALG_X_CAST, "CAST", ESP_CAST_BLKS, ESP_CAST_IVS, - 5, 16, 8 | 1, + 5, 16, 8, cast5_encrypt, cast5_decrypt - }, - { ALG_ENC_CAST, "Skipjack", - ESP_SKIPJACK_BLKS, ESP_SKIPJACK_IVS, - 10, 10, 8 | 1, - skipjack_encrypt, - skipjack_decrypt } }; static void -des1_encrypt(void *pxd, u_int8_t *blk) -{ - struct esp_new_xdata *xd = pxd; - des_ecb_encrypt(blk, blk, (caddr_t) (xd->edx_eks[0]), 1); -} - -static void -des1_decrypt(void *pxd, u_int8_t *blk) +des1_encrypt(struct tdb *tdb, u_int8_t *blk) { - struct esp_new_xdata *xd = pxd; - des_ecb_encrypt(blk, blk, (caddr_t) (xd->edx_eks[0]), 0); + des_ecb_encrypt(blk, blk, tdb->tdb_key, 1); } static void -des3_encrypt(void *pxd, u_int8_t *blk) +des1_decrypt(struct tdb *tdb, u_int8_t *blk) { - struct esp_new_xdata *xd = pxd; - des_ecb3_encrypt(blk, blk, (caddr_t) (xd->edx_eks[0]), - (caddr_t) (xd->edx_eks[1]), - (caddr_t) (xd->edx_eks[2]), 1); + des_ecb_encrypt(blk, blk, tdb->tdb_key, 0); } static void -des3_decrypt(void *pxd, u_int8_t *blk) +des3_encrypt(struct tdb *tdb, u_int8_t *blk) { - struct esp_new_xdata *xd = pxd; - des_ecb3_encrypt(blk, blk, (caddr_t) (xd->edx_eks[2]), - (caddr_t) (xd->edx_eks[1]), - (caddr_t) (xd->edx_eks[0]), 0); + des_ecb3_encrypt(blk, blk, tdb->tdb_key, tdb->tdb_key + 128, + tdb->tdb_key + 256, 1); } static void -blf_encrypt(void *pxd, u_int8_t *blk) +des3_decrypt(struct tdb *tdb, u_int8_t *blk) { - struct esp_new_xdata *xd = pxd; - Blowfish_encipher(&xd->edx_bks, (u_int32_t *) blk, - (u_int32_t *) (blk + 4)); + des_ecb3_encrypt(blk, blk, tdb->tdb_key + 256, tdb->tdb_key + 128, + tdb->tdb_key, 0); } static void -blf_decrypt(void *pxd, u_int8_t *blk) +blf_encrypt(struct tdb *tdb, u_int8_t *blk) { - struct esp_new_xdata *xd = pxd; - Blowfish_decipher(&xd->edx_bks, (u_int32_t *) blk, - (u_int32_t *) (blk + 4)); + blf_ecb_encrypt((blf_ctx *) tdb->tdb_key, blk, 8); } static void -cast5_encrypt(void *pxd, u_int8_t *blk) +blf_decrypt(struct tdb *tdb, u_int8_t *blk) { - struct esp_new_xdata *xd = pxd; - cast_encrypt(&xd->edx_cks, blk, blk); + blf_ecb_decrypt((blf_ctx *) tdb->tdb_key, blk, 8); } static void -cast5_decrypt(void *pxd, u_int8_t *blk) +cast5_encrypt(struct tdb *tdb, u_int8_t *blk) { - struct esp_new_xdata *xd = pxd; - cast_decrypt(&xd->edx_cks, blk, blk); + cast_encrypt((cast_key *) tdb->tdb_key, blk, blk); } static void -skipjack_encrypt(void *pxd, u_int8_t *blk) +cast5_decrypt(struct tdb *tdb, u_int8_t *blk) { - struct esp_new_xdata *xd = pxd; - skipjack_forwards(blk, blk, xd->edx_sks); -} - -static void -skipjack_decrypt(void *pxd, u_int8_t *blk) -{ - struct esp_new_xdata *xd = pxd; - skipjack_backwards(blk, blk, xd->edx_sks); + cast_decrypt((cast_key *) tdb->tdb_key, blk, blk); } /* * esp_new_attach() is called from the transformation initialization code. - * It just returns. */ int esp_new_attach() { - DPRINTF(("esp_new_attach(): setting up\n")); return 0; } /* - * esp_new_init() is called when an SPI is being set up. It interprets the - * encap_msghdr present in m, and sets up the transformation data, in - * this case, the encryption and decryption key schedules + * esp_new_init() is called when an SPI is being set up. */ int -esp_new_init(struct tdb *tdbp, struct xformsw *xsp, struct mbuf *m) +esp_new_init(struct tdb *tdbp, struct xformsw *xsp, struct ipsecinit *ii) { - struct esp_new_xdata *xd; - struct esp_new_xencap txd; - struct encap_msghdr *em; - struct esp_xform *txform; - struct esp_hash *thash; - caddr_t buffer = NULL; - u_int32_t rk[14]; - int blocklen, i; - - if (m->m_len < ENCAP_MSG_FIXED_LEN) - { - if ((m = m_pullup(m, ENCAP_MSG_FIXED_LEN)) == NULL) - { - DPRINTF(("esp_new_init(): m_pullup failed\n")); - return ENOBUFS; - } - } - - em = mtod(m, struct encap_msghdr *); - if (em->em_msglen - EMT_SETSPI_FLEN <= ESP_NEW_XENCAP_LEN) - { - DPRINTF(("esp_new_init(): initialization failed\n")); - return EINVAL; - } - - /* Just copy the standard fields */ - m_copydata(m, EMT_SETSPI_FLEN, ESP_NEW_XENCAP_LEN, (caddr_t) &txd); + struct enc_xform *txform = NULL; + struct auth_hash *thash = NULL; + int i; /* Check whether the encryption algorithm is supported */ - for (i = sizeof(esp_new_xform) / sizeof(struct esp_xform) - 1; i >= 0; i--) - if (txd.edx_enc_algorithm == esp_new_xform[i].type) - break; + for (i = sizeof(esp_new_xform) / sizeof(struct enc_xform) - 1; + i >= 0; i--) + if (ii->ii_encalg == esp_new_xform[i].type) + break; + if (i < 0) { - DPRINTF(("esp_new_init(): unsupported encryption algorithm %d specified\n", txd.edx_enc_algorithm)); + DPRINTF(("esp_new_init(): unsupported encryption algorithm %d specified\n", ii->ii_encalg)); return EINVAL; } txform = &esp_new_xform[i]; - DPRINTF(("esp_new_init(): initialized TDB with enc algorithm %d: %s\n", - txd.edx_enc_algorithm, esp_new_xform[i].name)); - /* Check whether the authentication algorithm is supported */ - if (txd.edx_flags & ESP_NEW_FLAG_AUTH) + if (ii->ii_enckeylen < txform->minkey) { - for (i = sizeof(esp_new_hash) / sizeof(struct esp_hash) - 1; i >= 0; - i--) - if (txd.edx_hash_algorithm == esp_new_hash[i].type) - break; - if (i < 0) - { - DPRINTF(("esp_new_init(): unsupported authentication algorithm %d specified\n", txd.edx_hash_algorithm)); - return EINVAL; - } - - DPRINTF(("esp_new_init(): initialized TDB with hash algorithm %d: %s\n", - txd.edx_hash_algorithm, esp_new_hash[i].name)); - blocklen = HMAC_BLOCK_LEN; - thash = &esp_new_hash[i]; - } - - if (txd.edx_ivlen + txd.edx_confkeylen + txd.edx_authkeylen + - EMT_SETSPI_FLEN + ESP_NEW_XENCAP_LEN != em->em_msglen) - { - if (encdebug) - DPRINTF(("esp_new_init(): message length (%d) doesn't match\n", em->em_msglen)); + DPRINTF(("esp_new_init(): keylength %d too small (min length is %d) for algorithm %s\n", ii->ii_enckeylen, txform->minkey, txform->name)); return EINVAL; } - - /* Check the IV length */ - if (((txd.edx_ivlen == 0) && !(txform->ivmask&1)) || - ((txd.edx_ivlen != 0) && ( - !(txd.edx_ivlen & txform->ivmask) || - (txd.edx_ivlen & (txd.edx_ivlen - 1))))) + + if (ii->ii_enckeylen > txform->maxkey) { - DPRINTF(("esp_new_init(): unsupported IV length %d\n", txd.edx_ivlen)); + DPRINTF(("esp_new_init(): keylength %d too large (max length is %d) for algorithm %s\n", ii->ii_enckeylen, txform->maxkey, txform->name)); return EINVAL; } - /* Check the key length */ - if (txd.edx_confkeylen < txform->minkey || - txd.edx_confkeylen > txform->maxkey) + if (ii->ii_authalg) { - DPRINTF(("esp_new_init(): bad key length %d\n", txd.edx_confkeylen)); - return EINVAL; - } + for (i = sizeof(esp_new_hash) / sizeof(struct auth_hash) - 1; + i >= 0; i--) + if (ii->ii_authalg == esp_new_hash[i].type) + break; - MALLOC(tdbp->tdb_xdata, caddr_t, sizeof(struct esp_new_xdata), - M_XDATA, M_WAITOK); - if (tdbp->tdb_xdata == NULL) - { - DPRINTF(("esp_new_init(): MALLOC() failed\n")); - return ENOBUFS; - } + if (i < 0) + { + DPRINTF(("esp_new_init(): unsupported authentication algorithm %d specified\n", ii->ii_authalg)); + return EINVAL; + } - bzero(tdbp->tdb_xdata, sizeof(struct esp_new_xdata)); - xd = (struct esp_new_xdata *) tdbp->tdb_xdata; + thash = &esp_new_hash[i]; - /* Pointer to the transform */ - tdbp->tdb_xform = xsp; + if (ii->ii_authkeylen != thash->keysize) + { + DPRINTF(("esp_new_init(): keylength %d doesn't match algorithm %s keysize (%d)\n", ii->ii_authkeylen, thash->name, thash->keysize)); + return EINVAL; + } + + tdbp->tdb_authalgxform = thash; - xd->edx_ivlen = txd.edx_ivlen; - xd->edx_enc_algorithm = txd.edx_enc_algorithm; - xd->edx_wnd = txd.edx_wnd; - xd->edx_flags = txd.edx_flags; - xd->edx_hash_algorithm = txd.edx_hash_algorithm; - xd->edx_bitmap = 0; - xd->edx_xform = txform; + DPRINTF(("esp_new_init(): initialized TDB with hash algorithm %s\n", + thash->name)); + } + + tdbp->tdb_xform = xsp; + tdbp->tdb_encalgxform = txform; + tdbp->tdb_bitmap = 0; + tdbp->tdb_rpl = AH_HMAC_INITIAL_RPL; - /* Pass name of enc algorithm for kernfs */ - tdbp->tdb_confname = xd->edx_xform->name; + DPRINTF(("esp_new_init(): initialized TDB with enc algorithm %s\n", + txform->name)); - /* Replay counters are mandatory, even without auth */ - xd->edx_rpl = AH_HMAC_INITIAL_RPL; + tdbp->tdb_ivlen = txform->ivmask; - /* Copy the IV */ - m_copydata(m, EMT_SETSPI_FLEN + ESP_NEW_XENCAP_LEN, xd->edx_ivlen, - (caddr_t) xd->edx_iv); + /* Initialize the IV */ + get_random_bytes(tdbp->tdb_iv, tdbp->tdb_ivlen); - /* Copy the key material */ - m_copydata(m, EMT_SETSPI_FLEN + ESP_NEW_XENCAP_LEN + xd->edx_ivlen, - txd.edx_confkeylen, (caddr_t) rk); - switch (xd->edx_enc_algorithm) + switch (ii->ii_encalg) { - case ALG_ENC_DES: - des_set_key((caddr_t) rk, (caddr_t) (xd->edx_eks[0])); + case SADB_EALG_DESCBC: + MALLOC(tdbp->tdb_key, u_int8_t *, 128, M_XDATA, M_WAITOK); + bzero(tdbp->tdb_key, 128); + des_set_key(ii->ii_enckey, tdbp->tdb_key); break; - case ALG_ENC_3DES: - des_set_key((caddr_t) rk, (caddr_t) (xd->edx_eks[0])); - des_set_key((caddr_t) (rk + 2), (caddr_t) (xd->edx_eks[1])); - des_set_key((caddr_t) (rk + 4), (caddr_t) (xd->edx_eks[2])); - break; - case ALG_ENC_BLF: - blf_key(&xd->edx_bks, (caddr_t) rk, txd.edx_confkeylen); + case SADB_EALG_3DESCBC: + MALLOC(tdbp->tdb_key, u_int8_t *, 384, M_XDATA, M_WAITOK); + bzero(tdbp->tdb_key, 384); + des_set_key(ii->ii_enckey, tdbp->tdb_key); + des_set_key(ii->ii_enckey + 8, tdbp->tdb_key + 128); + des_set_key(ii->ii_enckey + 16, tdbp->tdb_key + 256); break; - case ALG_ENC_CAST: - cast_setkey(&xd->edx_cks, (caddr_t) rk, txd.edx_confkeylen); + + case SADB_EALG_X_BLF: + MALLOC(tdbp->tdb_key, u_int8_t *, sizeof(blf_ctx), + M_XDATA, M_WAITOK); + bzero(tdbp->tdb_key, sizeof(blf_ctx)); + blf_key((blf_ctx *) tdbp->tdb_key, ii->ii_enckey, + ii->ii_enckeylen); break; - case ALG_ENC_SKIPJACK: - subkey_table_gen((caddr_t) rk, xd->edx_sks); + + case SADB_EALG_X_CAST: + MALLOC(tdbp->tdb_key, u_int8_t *, sizeof(cast_key), + M_XDATA, M_WAITOK); + bzero(tdbp->tdb_key, sizeof(cast_key)); + cast_setkey((cast_key *) tdbp->tdb_key, ii->ii_enckey, + ii->ii_enckeylen); break; } - if (txd.edx_flags & ESP_NEW_FLAG_AUTH) + if (thash) { - xd->edx_hash = thash; - - /* Pass name of auth algorithm for kernfs */ - tdbp->tdb_authname = xd->edx_hash->name; - - DPRINTF(("esp_new_init(): using %d bytes of authentication key\n", - txd.edx_authkeylen)); - - MALLOC(buffer, caddr_t, - txd.edx_authkeylen < blocklen ? blocklen : txd.edx_authkeylen, - M_TEMP, M_WAITOK); - if (buffer == NULL) - { - DPRINTF(("esp_new_init(): MALLOC() failed\n")); - free(tdbp->tdb_xdata, M_XDATA); - return ENOBUFS; - } - - bzero(buffer, txd.edx_authkeylen < blocklen ? - blocklen : txd.edx_authkeylen); - - /* Copy the key to the buffer */ - m_copydata(m, EMT_SETSPI_FLEN + ESP_NEW_XENCAP_LEN + xd->edx_ivlen + - txd.edx_confkeylen, txd.edx_authkeylen, buffer); - - /* Shorten the key if necessary */ - if (txd.edx_authkeylen > blocklen) - { - xd->edx_hash->Init(&(xd->edx_ictx)); - xd->edx_hash->Update(&(xd->edx_ictx), buffer, txd.edx_authkeylen); - bzero(buffer, txd.edx_authkeylen < blocklen ? - blocklen : txd.edx_authkeylen); - xd->edx_hash->Final(buffer, &(xd->edx_ictx)); - } - /* Precompute the I and O pads of the HMAC */ - for (i = 0; i < blocklen; i++) - buffer[i] ^= HMAC_IPAD_VAL; - - xd->edx_hash->Init(&(xd->edx_ictx)); - xd->edx_hash->Update(&(xd->edx_ictx), buffer, blocklen); + for (i = 0; i < ii->ii_authkeylen; i++) + ii->ii_authkey[i] ^= HMAC_IPAD_VAL; + + MALLOC(tdbp->tdb_ictx, u_int8_t *, thash->ctxsize, M_XDATA, M_WAITOK); + bzero(tdbp->tdb_ictx, thash->ctxsize); + thash->Init(tdbp->tdb_ictx); + thash->Update(tdbp->tdb_ictx, ii->ii_authkey, ii->ii_authkeylen); + thash->Update(tdbp->tdb_ictx, hmac_ipad_buffer, + HMAC_BLOCK_LEN - ii->ii_authkeylen); - for (i = 0; i < blocklen; i++) - buffer[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL); - - xd->edx_hash->Init(&(xd->edx_octx)); - xd->edx_hash->Update(&(xd->edx_octx), buffer, blocklen); - - bzero(buffer, blocklen); - free(buffer, M_TEMP); + for (i = 0; i < ii->ii_authkeylen; i++) + ii->ii_authkey[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL); + + MALLOC(tdbp->tdb_octx, u_int8_t *, thash->ctxsize, M_XDATA, M_WAITOK); + bzero(tdbp->tdb_octx, thash->ctxsize); + thash->Init(tdbp->tdb_octx); + thash->Update(tdbp->tdb_octx, ii->ii_authkey, ii->ii_authkeylen); + thash->Update(tdbp->tdb_octx, hmac_opad_buffer, + HMAC_BLOCK_LEN - ii->ii_authkeylen); } - bzero(rk, 14 * sizeof(u_int32_t)); /* paranoid */ - bzero(ipseczeroes, IPSEC_ZEROES_SIZE); /* paranoid */ - return 0; } int esp_new_zeroize(struct tdb *tdbp) { - struct esp_new_xdata *xd = (struct esp_new_xdata *) tdbp->tdb_xdata; - - DPRINTF(("esp_new_zeroize(): freeing memory\n")); - if (xd->edx_enc_algorithm == ALG_ENC_SKIPJACK) { - int k; + if (tdbp->tdb_key) + { + FREE(tdbp->tdb_key, M_XDATA); + tdbp->tdb_key = NULL; + } - for (k = 0; k < 10; k++) - free(xd->edx_sks[k], M_TEMP); + if (tdbp->tdb_ictx) + { + FREE(tdbp->tdb_ictx, M_XDATA); + tdbp->tdb_ictx = NULL; } - if (tdbp->tdb_xdata) + if (tdbp->tdb_octx) { - FREE(tdbp->tdb_xdata, M_XDATA); - tdbp->tdb_xdata = NULL; + FREE(tdbp->tdb_octx, M_XDATA); + tdbp->tdb_octx = NULL; } + return 0; } @@ -475,10 +364,11 @@ esp_new_zeroize(struct tdb *tdbp) struct mbuf * esp_new_input(struct mbuf *m, struct tdb *tdb) { + struct enc_xform *espx = (struct enc_xform *) tdb->tdb_encalgxform; + struct auth_hash *esph = (struct auth_hash *) tdb->tdb_authalgxform; u_char iv[ESP_MAX_IVS], niv[ESP_MAX_IVS]; u_char blk[ESP_MAX_BLKS], *lblk, opts[40]; int ohlen, oplen, plen, alen, ilen, i, blks, rest; - struct esp_new_xdata *xd; int count, off, errc; struct mbuf *mi, *mo; u_char *idat, *odat, *ivp, *ivn; @@ -492,11 +382,9 @@ esp_new_input(struct mbuf *m, struct tdb *tdb) } ctx; u_char buf[AH_ALEN_MAX], buf2[AH_ALEN_MAX]; - xd = (struct esp_new_xdata *) tdb->tdb_xdata; + blks = espx->blocksize; - blks = xd->edx_xform->blocksize; - - if (xd->edx_flags & ESP_NEW_FLAG_AUTH) + if (esph) alen = AH_HMAC_HASHLEN; else alen = 0; @@ -527,26 +415,52 @@ esp_new_input(struct mbuf *m, struct tdb *tdb) ip = mtod(m, struct ip *); } + /* Update the counters */ + tdb->tdb_cur_bytes += ip->ip_len - ohlen - alen; + espstat.esps_ibytes += ip->ip_len - ohlen - alen; + + /* Hard expiration */ + if ((tdb->tdb_flags & TDBF_BYTES) && + (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes)) + { +/* XXX + encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); +*/ + tdb_delete(tdb, 0); + m_freem(m); + return NULL; + } + + /* Notify on expiration */ + if ((tdb->tdb_flags & TDBF_SOFT_BYTES) && + (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes)) + { +/* XXX + encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); +*/ + tdb->tdb_flags &= ~TDBF_SOFT_BYTES; /* Turn off checking */ + } + esp = (struct esp_new *) ((u_int8_t *) ip + (ip->ip_hl << 2)); ipo = *ip; /* Replay window checking */ - if (xd->edx_wnd >= 0) + if (tdb->tdb_wnd > 0) { btsx = ntohl(esp->esp_rpl); - if ((errc = checkreplaywindow32(btsx, 0, &(xd->edx_rpl), xd->edx_wnd, - &(xd->edx_bitmap))) != 0) + if ((errc = checkreplaywindow32(btsx, 0, &(tdb->tdb_rpl), tdb->tdb_wnd, + &(tdb->tdb_bitmap))) != 0) { switch(errc) { case 1: - DPRINTF(("esp_new_input(): replay counter wrapped for packets from %x to %x, spi %08x\n", ip->ip_src, ip->ip_dst, ntohl(esp->esp_spi))); + DPRINTF(("esp_new_input(): replay counter wrapped for packets from %s to %s, spi %08x\n", inet_ntoa4(ip->ip_src), inet_ntoa4(ip->ip_dst), ntohl(esp->esp_spi))); espstat.esps_wrap++; break; case 2: case 3: - DPRINTF(("esp_new_input(): duplicate packet received, %x->%x spi %08x\n", ip->ip_src, ip->ip_dst, ntohl(esp->esp_spi))); + DPRINTF(("esp_new_input(): duplicate packet received from %s to %s, spi %08x\n", inet_ntoa4(ip->ip_src), inet_ntoa4(ip->ip_dst), ntohl(esp->esp_spi))); espstat.esps_replay++; break; } @@ -558,22 +472,22 @@ esp_new_input(struct mbuf *m, struct tdb *tdb) /* Skip the IP header, IP options, SPI, SN and IV and minus Auth Data */ plen = m->m_pkthdr.len - (ip->ip_hl << 2) - 2 * sizeof(u_int32_t) - - xd->edx_ivlen - alen; + tdb->tdb_ivlen - alen; if ((plen & (blks - 1)) || (plen <= 0)) { - DPRINTF(("esp_new_input(): payload not a multiple of %d octets for packet from %x to %x, spi %08x\n", blks, ipo.ip_src, ipo.ip_dst, ntohl(tdb->tdb_spi))); + DPRINTF(("esp_new_input(): payload not a multiple of %d octets for packet from %s to %s, spi %08x\n", blks, inet_ntoa4(ipo.ip_src), inet_ntoa4(ipo.ip_dst), ntohl(tdb->tdb_spi))); espstat.esps_badilen++; m_freem(m); return NULL; } - if (xd->edx_flags & ESP_NEW_FLAG_AUTH) + if (esph) { - bcopy(&(xd->edx_ictx), &ctx, xd->edx_hash->ctxsize); + bcopy(tdb->tdb_ictx, &ctx, esph->ctxsize); /* Auth covers SPI + SN + IV */ - oplen = plen + 2 * sizeof(u_int32_t) + xd->edx_ivlen; + oplen = plen + 2 * sizeof(u_int32_t) + tdb->tdb_ivlen; off = (ip->ip_hl << 2); /* Copy the authentication data */ @@ -585,27 +499,27 @@ esp_new_input(struct mbuf *m, struct tdb *tdb) { if (mo == 0) { - DPRINTF(("esp_new_input(): bad mbuf chain for packet from %x to %x, spi %08x\n", ip->ip_src, ip->ip_dst, ntohl(esp->esp_spi))); + DPRINTF(("esp_new_input(): bad mbuf chain for packet from %s to %s, spi %08x\n", inet_ntoa4(ip->ip_src), inet_ntoa4(ip->ip_dst), ntohl(esp->esp_spi))); espstat.esps_hdrops++; m_freem(m); return NULL; } count = min(mo->m_len - off, oplen); - xd->edx_hash->Update(&ctx, mtod(mo, unsigned char *) + off, count); + esph->Update(&ctx, mtod(mo, unsigned char *) + off, count); oplen -= count; off = 0; mo = mo->m_next; } - xd->edx_hash->Final(buf2, &ctx); - bcopy(&(xd->edx_octx), &ctx, xd->edx_hash->ctxsize); - xd->edx_hash->Update(&ctx, buf2, xd->edx_hash->hashsize); - xd->edx_hash->Final(buf2, &ctx); + esph->Final(buf2, &ctx); + bcopy(tdb->tdb_octx, &ctx, esph->ctxsize); + esph->Update(&ctx, buf2, esph->hashsize); + esph->Final(buf2, &ctx); if (bcmp(buf2, buf, AH_HMAC_HASHLEN)) { - DPRINTF(("esp_new_input(): authentication failed for packet from %x to %x, spi %08x\n", ip->ip_src, ip->ip_dst, ntohl(esp->esp_spi))); + DPRINTF(("esp_new_input(): authentication failed for packet from %s to %s, spi %08x\n", inet_ntoa4(ip->ip_src), inet_ntoa4(ip->ip_dst), ntohl(esp->esp_spi))); espstat.esps_badauth++; m_freem(m); return NULL; @@ -616,21 +530,10 @@ esp_new_input(struct mbuf *m, struct tdb *tdb) ilen = m->m_len - (ip->ip_hl << 2) - 2 * sizeof(u_int32_t); idat = mtod(m, unsigned char *) + (ip->ip_hl << 2) + 2 * sizeof(u_int32_t); - if (xd->edx_ivlen == 0) /* Derived IV in use */ - { - bcopy((u_char *) &esp->esp_rpl, iv, sizeof(esp->esp_rpl)); - iv[4] = ~iv[0]; - iv[5] = ~iv[1]; - iv[6] = ~iv[2]; - iv[7] = ~iv[3]; - } - else - { - bcopy(idat, iv, xd->edx_ivlen); - ilen -= xd->edx_ivlen; - idat += xd->edx_ivlen; - } - + bcopy(idat, iv, tdb->tdb_ivlen); + ilen -= tdb->tdb_ivlen; + idat += tdb->tdb_ivlen; + mi = m; /* @@ -666,7 +569,7 @@ esp_new_input(struct mbuf *m, struct tdb *tdb) mi = (mo = mi)->m_next; if (mi == NULL) { - DPRINTF(("esp_new_input(): bad mbuf chain, SA %x/%08x\n", tdb->tdb_dst, ntohl(tdb->tdb_spi))); + DPRINTF(("esp_new_input(): bad mbuf chain, SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); espstat.esps_hdrops++; m_freem(m); return NULL; @@ -677,7 +580,7 @@ esp_new_input(struct mbuf *m, struct tdb *tdb) { if ((mi = m_pullup(mi, blks - rest)) == NULL) { - DPRINTF(("esp_new_input(): m_pullup() failed, SA %x/%08x\n", tdb->tdb_dst, ntohl(tdb->tdb_spi))); + DPRINTF(("esp_new_input(): m_pullup() failed, SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); m_freem(m); espstat.esps_hdrops++; return NULL; @@ -697,7 +600,7 @@ esp_new_input(struct mbuf *m, struct tdb *tdb) bcopy(idat, blk + rest, blks - rest); bcopy(blk, ivn, blks); - xd->edx_xform->decrypt(xd, blk); + espx->decrypt(tdb, blk); for (i = 0; i < blks; i++) blk[i] ^= ivp[i]; @@ -722,7 +625,7 @@ esp_new_input(struct mbuf *m, struct tdb *tdb) { bcopy(idat, ivn, blks); - xd->edx_xform->decrypt(xd, idat); + espx->decrypt(tdb, idat); for (i = 0; i < blks; i++) idat[i] ^= ivp[i]; @@ -743,7 +646,7 @@ esp_new_input(struct mbuf *m, struct tdb *tdb) (caddr_t) opts); if (lblk != blk) - bcopy(lblk, blk, blks); + bcopy(lblk, blk, blks); /* * Now, the entire chain has been decrypted. As a side effect, @@ -753,58 +656,30 @@ esp_new_input(struct mbuf *m, struct tdb *tdb) * Verify correct decryption by checking the last padding bytes. */ - if ((xd->edx_flags & ESP_NEW_FLAG_NPADDING) == 0) + if (blk[blks - 2] + 2 + alen > m->m_pkthdr.len - (ip->ip_hl << 2) - 2 * sizeof(u_int32_t) - tdb->tdb_ivlen) { - if (blk[blks - 2] + 2 + alen > m->m_pkthdr.len - (ip->ip_hl << 2) - 2 * sizeof(u_int32_t) - xd->edx_ivlen) - { - DPRINTF(("esp_new_input(): invalid padding length %d for packet from %x to %x, SA %x/%08x\n", blk[blks - 2], ipo.ip_src, ipo.ip_dst, tdb->tdb_dst, ntohl(tdb->tdb_spi))); - espstat.esps_badilen++; - m_freem(m); - return NULL; - } - if ((blk[blks - 2] != blk[blks - 3]) && (blk[blks - 2] != 0)) - { - DPRINTF(("esp_new_input(): decryption failed for packet from %x to %x, SA %x/%08x\n", ipo.ip_src, ipo.ip_dst, tdb->tdb_dst, ntohl(tdb->tdb_spi))); - m_freem(m); - return NULL; - } - - m_adj(m, - blk[blks - 2] - 2 - alen); /* Old type padding */ + DPRINTF(("esp_new_input(): invalid padding length %d for packet from %s to %s, spi %08x\n", blk[blks - 2], inet_ntoa4(ipo.ip_src), inet_ntoa4(ipo.ip_dst), ntohl(tdb->tdb_spi))); + espstat.esps_badilen++; + m_freem(m); + return NULL; } - else + + if ((blk[blks - 2] != blk[blks - 3]) && (blk[blks - 2] != 0)) { - if (blk[blks - 2] + 1 + alen > m->m_pkthdr.len - (ip->ip_hl << 2) - 2 * sizeof(u_int32_t) - xd->edx_ivlen) - { - DPRINTF(("esp_new_input(): invalid padding length %d for packet from %x to %x, SA %x/%08x\n", blk[blks - 2], ipo.ip_src, ipo.ip_dst, tdb->tdb_dst, ntohl(tdb->tdb_spi))); - espstat.esps_badilen++; - m_freem(m); - return NULL; - } - if (blk[blks - 2] == 0) - { - DPRINTF(("esp_new_input(): decryption failed for packet from %x to %x, SA %x/%08x -- peer is probably using old style padding\n", ipo.ip_src, ipo.ip_dst, tdb->tdb_dst, ntohl(tdb->tdb_spi))); - m_freem(m); - return NULL; - } - else - if ((blk[blks - 2] != 1) && (blk[blks - 2] != blk[blks - 3] + 1)) - { - DPRINTF(("esp_new_input(): decryption failed for packet from %x to %x, SA %x/%08x\n", ipo.ip_src, ipo.ip_dst, tdb->tdb_dst, ntohl(tdb->tdb_spi))); - m_freem(m); - return NULL; - } - - m_adj(m, - blk[blks - 2] - 1 - alen); - } + DPRINTF(("esp_new_input(): decryption failed for packet from %s to %s, spi %08x\n", inet_ntoa4(ipo.ip_src), inet_ntoa4(ipo.ip_dst), ntohl(tdb->tdb_spi))); + m_freem(m); + return NULL; + } - m_adj(m, 2 * sizeof(u_int32_t) + xd->edx_ivlen); + m_adj(m, - blk[blks - 2] - 2 - alen); /* Old type padding */ + m_adj(m, 2 * sizeof(u_int32_t) + tdb->tdb_ivlen); if (m->m_len < (ipo.ip_hl << 2)) { m = m_pullup(m, (ipo.ip_hl << 2)); if (m == NULL) { - DPRINTF(("esp_new_input(): m_pullup() failed for packet from %x to %x, SA %x/%08x\n", ipo.ip_src, ipo.ip_dst, tdb->tdb_dst, ntohl(tdb->tdb_spi))); + DPRINTF(("esp_new_input(): m_pullup() failed for packet from %s to %s, spi %08x\n", inet_ntoa4(ipo.ip_src), inet_ntoa4(ipo.ip_dst), ntohl(tdb->tdb_spi))); espstat.esps_hdrops++; return NULL; } @@ -814,11 +689,8 @@ esp_new_input(struct mbuf *m, struct tdb *tdb) ipo.ip_p = blk[blks - 1]; ipo.ip_id = htons(ipo.ip_id); ipo.ip_off = 0; - ipo.ip_len += (ipo.ip_hl << 2) - 2 * sizeof(u_int32_t) - xd->edx_ivlen - - blk[blks - 2] - 1 - alen; - - if ((xd->edx_flags & ESP_NEW_FLAG_NPADDING) == 0) - ipo.ip_len -= 1; + ipo.ip_len += (ipo.ip_hl << 2) - 2 * sizeof(u_int32_t) - tdb->tdb_ivlen - + blk[blks - 2] - 2 - alen; ipo.ip_len = htons(ipo.ip_len); ipo.ip_sum = 0; @@ -830,52 +702,6 @@ esp_new_input(struct mbuf *m, struct tdb *tdb) ip->ip_sum = in_cksum(m, (ip->ip_hl << 2)); - /* Update the counters */ - tdb->tdb_cur_packets++; - tdb->tdb_cur_bytes += ntohs(ip->ip_len) - (ip->ip_hl << 2) + - blk[blks - 2] + 1 + alen; - espstat.esps_ibytes += ntohs(ip->ip_len) - (ip->ip_hl << 2) + - blk[blks - 2] + 1 + alen; - - if ((xd->edx_flags & ESP_NEW_FLAG_NPADDING) == 0) - { - tdb->tdb_cur_bytes++; - espstat.esps_ibytes++; - } - - /* Notify on expiration */ - if (tdb->tdb_flags & TDBF_SOFT_PACKETS) - { - if (tdb->tdb_cur_packets >= tdb->tdb_soft_packets) - { - encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); - tdb->tdb_flags &= ~TDBF_SOFT_PACKETS; - } - else - if (tdb->tdb_flags & TDBF_SOFT_BYTES) - if (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) - { - encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); - tdb->tdb_flags &= ~TDBF_SOFT_BYTES; - } - } - - if (tdb->tdb_flags & TDBF_PACKETS) - { - if (tdb->tdb_cur_packets >= tdb->tdb_exp_packets) - { - encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); - tdb_delete(tdb, 0); - } - else - if (tdb->tdb_flags & TDBF_BYTES) - if (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) - { - encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); - tdb_delete(tdb, 0); - } - } - return m; } @@ -883,7 +709,8 @@ int esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct mbuf **mp) { - struct esp_new_xdata *xd; + struct enc_xform *espx = (struct enc_xform *) tdb->tdb_encalgxform; + struct auth_hash *esph = (struct auth_hash *) tdb->tdb_authalgxform; struct ip *ip, ipo; int i, ilen, ohlen, nh, rlen, plen, padding, rest; struct esp_new espo; @@ -897,14 +724,12 @@ esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, } ctx; int iphlen, blks, alen; - xd = (struct esp_new_xdata *) tdb->tdb_xdata; + blks = espx->blocksize; - blks = xd->edx_xform->blocksize; - - if (xd->edx_flags & ESP_NEW_FLAG_AUTH) + if (esph) { alen = AH_HMAC_HASHLEN; - DPRINTF(("esp_new_output(): using hash algorithm: %s\n", xd->edx_hash->name)); + DPRINTF(("esp_new_output(): using hash algorithm: %s\n", esph->name)); } else alen = 0; @@ -914,27 +739,53 @@ esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, m = m_pullup(m, sizeof (struct ip)); /* Get IP header in one mbuf */ if (m == NULL) { - DPRINTF(("esp_new_output(): m_pullup() failed, SA %x/%08x\n", - tdb->tdb_dst, ntohl(tdb->tdb_spi))); + DPRINTF(("esp_new_output(): m_pullup() failed, SA %s/%08x\n", + ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); espstat.esps_hdrops++; return ENOBUFS; } - if (xd->edx_rpl == 0) + if (tdb->tdb_rpl == 0) { - DPRINTF(("esp_new_output(): SA %x/%0x8 should have expired\n", - tdb->tdb_dst, ntohl(tdb->tdb_spi))); + DPRINTF(("esp_new_output(): SA %s/%0x8 should have expired\n", + ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); m_freem(m); espstat.esps_wrap++; return ENOBUFS; } espo.esp_spi = tdb->tdb_spi; - espo.esp_rpl = htonl(xd->edx_rpl++); + espo.esp_rpl = htonl(tdb->tdb_rpl++); ip = mtod(m, struct ip *); iphlen = (ip->ip_hl << 2); + /* Update the counters */ + tdb->tdb_cur_bytes += ntohs(ip->ip_len) - (ip->ip_hl << 2); + espstat.esps_obytes += ntohs(ip->ip_len) - (ip->ip_hl << 2); + + /* Hard expiration */ + if ((tdb->tdb_flags & TDBF_BYTES) && + (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes)) + { +/* XXX + encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); +*/ + tdb_delete(tdb, 0); + m_freem(m); + return EINVAL; + } + + /* Notify on expiration */ + if ((tdb->tdb_flags & TDBF_SOFT_BYTES) && + (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes)) + { +/* XXX + encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); +*/ + tdb->tdb_flags &= ~TDBF_SOFT_BYTES; /* Turn off checking */ + } + /* * If options are present, pullup the IP header, the options. */ @@ -943,8 +794,8 @@ esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, m = m_pullup(m, iphlen + 8); if (m == NULL) { - DPRINTF(("esp_new_input(): m_pullup() failed for SA %x/%08x\n", - tdb->tdb_dst, ntohl(tdb->tdb_spi))); + DPRINTF(("esp_new_input(): m_pullup() failed for SA %s/%08x\n", + ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); espstat.esps_hdrops++; return ENOBUFS; } @@ -957,7 +808,7 @@ esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, } ilen = ntohs(ip->ip_len); /* Size of the packet */ - ohlen = 2 * sizeof(u_int32_t) + xd->edx_ivlen; + ohlen = 2 * sizeof(u_int32_t) + tdb->tdb_ivlen; ipo = *ip; nh = ipo.ip_p; @@ -965,9 +816,10 @@ esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, /* Raw payload length */ rlen = ilen - iphlen; padding = ((blks - ((rlen + 2) % blks)) % blks) + 2; - if (iphlen + ohlen + rlen + padding + alen > IP_MAXPACKET) { - DPRINTF(("esp_new_output(): packet in SA %x/%0x8 got too big\n", - tdb->tdb_dst, ntohl(tdb->tdb_spi))); + if (iphlen + ohlen + rlen + padding + alen > IP_MAXPACKET) + { + DPRINTF(("esp_new_output(): packet in SA %s/%0x8 got too big\n", + ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); m_freem(m); espstat.esps_toobig++; return EMSGSIZE; @@ -976,8 +828,8 @@ esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, pad = (u_char *) m_pad(m, padding + alen, 0); if (pad == NULL) { - DPRINTF(("esp_new_output(): m_pad() failed for SA %x/%08x\n", - tdb->tdb_dst, ntohl(tdb->tdb_spi))); + DPRINTF(("esp_new_output(): m_pad() failed for SA %s/%08x\n", + ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); return ENOBUFS; } @@ -985,11 +837,7 @@ esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, for (i = 0; i < padding - 2; i++) pad[i] = i + 1; - if (xd->edx_flags & ESP_NEW_FLAG_NPADDING) - pad[padding - 2] = padding - 1; - else - pad[padding - 2] = padding - 2; - + pad[padding - 2] = padding - 2; pad[padding - 1] = nh; mi = m; @@ -997,26 +845,15 @@ esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, ilen = m->m_len - iphlen; idat = mtod(m, u_char *) + iphlen; - if (xd->edx_ivlen == 0) - { - bcopy((u_char *) &espo.esp_rpl, iv, 4); - iv[4] = ~iv[0]; - iv[5] = ~iv[1]; - iv[6] = ~iv[2]; - iv[7] = ~iv[3]; - } - else - { - bcopy(xd->edx_iv, iv, xd->edx_ivlen); - bcopy(xd->edx_iv, espo.esp_iv, xd->edx_ivlen); - } + bcopy(tdb->tdb_iv, iv, tdb->tdb_ivlen); + bcopy(tdb->tdb_iv, espo.esp_iv, tdb->tdb_ivlen); /* Authenticate the esp header */ - if (xd->edx_flags & ESP_NEW_FLAG_AUTH) + if (esph) { - bcopy(&(xd->edx_ictx), &ctx, xd->edx_hash->ctxsize); - xd->edx_hash->Update(&ctx, (unsigned char *) &espo, - 2 * sizeof(u_int32_t) + xd->edx_ivlen); + bcopy(tdb->tdb_ictx, &ctx, esph->ctxsize); + esph->Update(&ctx, (unsigned char *) &espo, + 2 * sizeof(u_int32_t) + tdb->tdb_ivlen); } /* Encrypt the payload */ @@ -1043,7 +880,8 @@ esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, mi = (mo = mi)->m_next; if (mi == NULL) { - DPRINTF(("esp_new_output(): bad mbuf chain, SA %x/%08x\n", tdb->tdb_dst, ntohl(tdb->tdb_spi))); + DPRINTF(("esp_new_output(): bad mbuf chain, SA %s/%08x\n", + ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); espstat.esps_hdrops++; m_freem(m); return EINVAL; @@ -1054,7 +892,7 @@ esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, { if ((mi = m_pullup(mi, blks - rest)) == NULL) { - DPRINTF(("esp_new_output(): m_pullup() failed, SA %x/%08x\n", tdb->tdb_dst, ntohl(tdb->tdb_spi))); + DPRINTF(("esp_new_output(): m_pullup() failed, SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); m_freem(m); espstat.esps_hdrops++; return ENOBUFS; @@ -1076,10 +914,10 @@ esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, for (i = 0; i < blks; i++) blk[i] ^= ivp[i]; - xd->edx_xform->encrypt(xd, blk); + espx->encrypt(tdb, blk); - if (xd->edx_flags & ESP_NEW_FLAG_AUTH) - xd->edx_hash->Update(&ctx, blk, blks); + if (esph) + esph->Update(&ctx, blk, blks); ivp = blk; @@ -1099,10 +937,10 @@ esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, for (i = 0; i < blks; i++) idat[i] ^= ivp[i]; - xd->edx_xform->encrypt(xd, idat); + espx->encrypt(tdb, idat); - if (xd->edx_flags & ESP_NEW_FLAG_AUTH) - xd->edx_hash->Update(&ctx, idat, blks); + if (esph) + esph->Update(&ctx, idat, blks); ivp = idat; idat += blks; @@ -1113,12 +951,12 @@ esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, } /* Put in authentication data */ - if (xd->edx_flags & ESP_NEW_FLAG_AUTH) + if (esph) { - xd->edx_hash->Final(auth, &ctx); - bcopy(&(xd->edx_octx), &ctx, xd->edx_hash->ctxsize); - xd->edx_hash->Update(&ctx, auth, xd->edx_hash->hashsize); - xd->edx_hash->Final(auth, &ctx); + esph->Final(auth, &ctx); + bcopy(tdb->tdb_octx, &ctx, esph->ctxsize); + esph->Update(&ctx, auth, esph->hashsize); + esph->Final(auth, &ctx); /* Copy the final authenticator */ bcopy(auth, pad + padding, alen); @@ -1132,16 +970,16 @@ esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, M_PREPEND(m, ohlen, M_DONTWAIT); if (m == NULL) { - DPRINTF(("esp_new_output(): M_PREPEND failed, SA %x/%08x\n", - tdb->tdb_dst, ntohl(tdb->tdb_spi))); + DPRINTF(("esp_new_output(): M_PREPEND failed, SA %s/%08x\n", + ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); return ENOBUFS; } m = m_pullup(m, iphlen + ohlen); if (m == NULL) { - DPRINTF(("esp_new_output(): m_pullup() failed, SA %x/%08x\n", - tdb->tdb_dst, ntohl(tdb->tdb_spi))); + DPRINTF(("esp_new_output(): m_pullup() failed, SA %s/%08x\n", + ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); espstat.esps_hdrops++; return ENOBUFS; } @@ -1151,7 +989,7 @@ esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, ipo.ip_p = IPPROTO_ESP; /* Save the last encrypted block, to be used as the next IV */ - bcopy(ivp, xd->edx_iv, xd->edx_ivlen); + bcopy(ivp, tdb->tdb_iv, tdb->tdb_ivlen); m_copyback(m, 0, sizeof(struct ip), (caddr_t) &ipo); @@ -1165,44 +1003,6 @@ esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, *mp = m; - /* Update the counters */ - tdb->tdb_cur_packets++; - tdb->tdb_cur_bytes += rlen + padding; - espstat.esps_obytes += rlen + padding; - - /* Notify on expiration */ - if (tdb->tdb_flags & TDBF_SOFT_PACKETS) - { - if (tdb->tdb_cur_packets >= tdb->tdb_soft_packets) - { - encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); - tdb->tdb_flags &= ~TDBF_SOFT_PACKETS; - } - else - if (tdb->tdb_flags & TDBF_SOFT_BYTES) - if (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) - { - encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); - tdb->tdb_flags &= ~TDBF_SOFT_BYTES; - } - } - - if (tdb->tdb_flags & TDBF_PACKETS) - { - if (tdb->tdb_cur_packets >= tdb->tdb_exp_packets) - { - encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); - tdb_delete(tdb, 0); - } - else - if (tdb->tdb_flags & TDBF_BYTES) - if (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) - { - encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); - tdb_delete(tdb, 0); - } - } - return 0; } @@ -1250,3 +1050,4 @@ checkreplaywindow32(u_int32_t seq, u_int32_t initial, u_int32_t *lastseq, *bitmap |= (((u_int32_t) 1) << diff); return 0; } + |