Index: sys/netipsec/xform.h =================================================================== --- sys/netipsec/xform.h +++ sys/netipsec/xform.h @@ -110,7 +110,7 @@ struct cryptoini; /* XF_AH */ int xform_ah_authsize(const struct auth_hash *); -extern int ah_init0(struct secasvar *, struct xformsw *, struct cryptoini *); +extern int ah_init0(struct secasvar *, struct xformsw *, struct cryptoini *, struct cryptoini *); extern int ah_zeroize(struct secasvar *sav); extern size_t ah_hdrsiz(struct secasvar *); Index: sys/netipsec/xform_ah.c =================================================================== --- sys/netipsec/xform_ah.c +++ sys/netipsec/xform_ah.c @@ -174,7 +174,7 @@ * NB: public for use by esp_init. */ int -ah_init0(struct secasvar *sav, struct xformsw *xsp, struct cryptoini *cria) +ah_init0(struct secasvar *sav, struct xformsw *xsp, struct cryptoini *cria, struct cryptoini *crin) { const struct auth_hash *thash; int keylen; @@ -241,6 +241,13 @@ cria->cri_key = sav->key_auth->key_data; cria->cri_mlen = AUTHSIZE(sav); + if (sav->flags & SADB_X_SAFLAGS_ESN && + sav->replay != NULL && sav->replay->wsize != 0) { + bzero(crin, sizeof(*crin)); + crin->cri_alg = CRYPTO_ESN; + cria->cri_next = crin; + } + return 0; } @@ -250,10 +257,10 @@ static int ah_init(struct secasvar *sav, struct xformsw *xsp) { - struct cryptoini cria; + struct cryptoini cria, crin; int error; - error = ah_init0(sav, xsp, &cria); + error = ah_init0(sav, xsp, &cria, &crin); return error ? error : crypto_newsession(&sav->tdb_cryptoid, &cria, V_crypto_support); } @@ -648,6 +655,13 @@ crda->crd_klen = _KEYBITS(sav->key_auth); crda->crd_key = sav->key_auth->key_data; + if (sav->flags & SADB_X_SAFLAGS_ESN && + sav->replay != NULL && sav->replay->wsize != 0) { + seqh = htonl(seqh); + memcpy(crda->crd_esn, &seqh, 4); + crda->crd_flags |= CRD_F_ESN; + } + /* Allocate IPsec-specific opaque crypto info. */ xd = malloc(sizeof(*xd) + skip + rplen + authsize, M_XDATA, M_NOWAIT | M_ZERO); @@ -874,6 +888,7 @@ uint16_t iplen; int error, rplen, authsize, ahsize, maxpacketsize, roff; uint8_t prot; + uint32_t seqh; IPSEC_ASSERT(sav != NULL, ("null SA")); ahx = sav->tdb_authalgxform; @@ -1008,6 +1023,12 @@ crda->crd_key = sav->key_auth->key_data; crda->crd_klen = _KEYBITS(sav->key_auth); + if (sav->flags & SADB_X_SAFLAGS_ESN && sav->replay != NULL) { + seqh = htonl((uint32_t)(sav->replay->count >> 32)); + memcpy(crda->crd_esn, &seqh, 4); + crda->crd_flags |= CRD_F_ESN; + } + /* Allocate IPsec-specific opaque crypto info. */ xd = malloc(sizeof(struct xform_data) + skip, M_XDATA, M_NOWAIT | M_ZERO); Index: sys/netipsec/xform_esp.c =================================================================== --- sys/netipsec/xform_esp.c +++ sys/netipsec/xform_esp.c @@ -137,7 +137,7 @@ esp_init(struct secasvar *sav, struct xformsw *xsp) { const struct enc_xform *txform; - struct cryptoini cria, crie; + struct cryptoini cria, crie, crin; int keylen; int error; @@ -197,7 +197,7 @@ * Setup AH-related state. */ if (sav->alg_auth != 0) { - error = ah_init0(sav, xsp, &cria); + error = ah_init0(sav, xsp, &cria, &crin); if (error) return error; } @@ -395,6 +395,13 @@ crda->crd_alg = esph->type; + if (sav->flags & SADB_X_SAFLAGS_ESN && + sav->replay != NULL && sav->replay->wsize != 0) { + seqh = htonl(seqh); + memcpy(crda->crd_esn, &seqh, 4); + crda->crd_flags |= CRD_F_ESN; + } + /* Copy the authenticator */ m_copydata(m, m->m_pkthdr.len - alen, alen, (caddr_t) (xd + 1)); @@ -665,6 +672,7 @@ int hlen, rlen, padding, blks, alen, i, roff; int error, maxpacketsize; uint8_t prot; + uint32_t seqh; IPSEC_ASSERT(sav != NULL, ("null SA")); esph = sav->tdb_authalgxform; @@ -887,6 +895,12 @@ else crda->crd_len = m->m_pkthdr.len - (skip + alen); crda->crd_inject = m->m_pkthdr.len - alen; + + if (sav->flags & SADB_X_SAFLAGS_ESN && sav->replay != NULL) { + seqh = htonl((uint32_t)(sav->replay->count >> 32)); + memcpy(crda->crd_esn, &seqh, 4); + crda->crd_flags |= CRD_F_ESN; + } } return crypto_dispatch(crp);