Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F112020498
D8468.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
19 KB
Referenced Files
None
Subscribers
None
D8468.diff
View Options
Index: head/lib/libipsec/pfkey.c
===================================================================
--- head/lib/libipsec/pfkey.c
+++ head/lib/libipsec/pfkey.c
@@ -1776,6 +1776,7 @@
case SADB_EXT_SPIRANGE:
case SADB_X_EXT_POLICY:
case SADB_X_EXT_SA2:
+ case SADB_X_EXT_SA_REPLAY:
mhp[ext->sadb_ext_type] = (caddr_t)ext;
break;
case SADB_X_EXT_NAT_T_TYPE:
Index: head/lib/libipsec/pfkey_dump.c
===================================================================
--- head/lib/libipsec/pfkey_dump.c
+++ head/lib/libipsec/pfkey_dump.c
@@ -219,6 +219,7 @@
struct sadb_key *m_auth, *m_enc;
struct sadb_ident *m_sid, *m_did;
struct sadb_sens *m_sens;
+ struct sadb_x_sa_replay *m_sa_replay;
/* check pfkey message. */
if (pfkey_align(m, mhp)) {
@@ -243,6 +244,7 @@
m_sid = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_SRC];
m_did = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_DST];
m_sens = (struct sadb_sens *)mhp[SADB_EXT_SENSITIVITY];
+ m_sa_replay = (struct sadb_x_sa_replay *)mhp[SADB_X_EXT_SA_REPLAY];
/* source address */
if (m_saddr == NULL) {
@@ -306,7 +308,8 @@
/* replay windoe size & flags */
printf("\tseq=0x%08x replay=%u flags=0x%08x ",
m_sa2->sadb_x_sa2_sequence,
- m_sa->sadb_sa_replay,
+ m_sa_replay ? (m_sa_replay->sadb_x_sa_replay_replay >> 3) :
+ m_sa->sadb_sa_replay,
m_sa->sadb_sa_flags);
/* state */
Index: head/sys/net/pfkeyv2.h
===================================================================
--- head/sys/net/pfkeyv2.h
+++ head/sys/net/pfkeyv2.h
@@ -283,6 +283,14 @@
};
_Static_assert(sizeof(struct sadb_x_nat_t_frag) == 8, "struct size mismatch");
+/* Additional large replay window support
+ */
+struct sadb_x_sa_replay {
+ u_int16_t sadb_x_sa_replay_len;
+ u_int16_t sadb_x_sa_replay_exttype;
+ u_int32_t sadb_x_sa_replay_replay; /* in packets */
+};
+_Static_assert(sizeof(struct sadb_x_sa_replay) == 8, "struct size mismatch");
#define SADB_EXT_RESERVED 0
#define SADB_EXT_SA 1
@@ -311,7 +319,8 @@
#define SADB_X_EXT_NAT_T_OAI 23 /* Peer's NAT_OA for src of SA. */
#define SADB_X_EXT_NAT_T_OAR 24 /* Peer's NAT_OA for dst of SA. */
#define SADB_X_EXT_NAT_T_FRAG 25 /* Manual MTU override. */
-#define SADB_EXT_MAX 25
+#define SADB_X_EXT_SA_REPLAY 26 /* Replay window override. */
+#define SADB_EXT_MAX 26
#define SADB_SATYPE_UNSPEC 0
#define SADB_SATYPE_AH 2
Index: head/sys/netipsec/ipsec.c
===================================================================
--- head/sys/netipsec/ipsec.c
+++ head/sys/netipsec/ipsec.c
@@ -251,7 +251,6 @@
#endif
static void ipsec_delpcbpolicy(struct inpcbpolicy *);
static struct secpolicy *ipsec_deepcopy_policy(struct secpolicy *src);
-static void vshiftl(unsigned char *, int, int);
MALLOC_DEFINE(M_IPSEC_INPCB, "inpcbpolicy", "inpcb-resident ipsec policy");
@@ -1476,57 +1475,70 @@
* beforehand).
* 0 (zero) is returned if packet disallowed, 1 if packet permitted.
*
- * Based on RFC 2401.
+ * Based on RFC 6479. Blocks are 32 bits unsigned integers
*/
+
+#define IPSEC_BITMAP_INDEX_MASK(w) (w - 1)
+#define IPSEC_REDUNDANT_BIT_SHIFTS 5
+#define IPSEC_REDUNDANT_BITS (1 << IPSEC_REDUNDANT_BIT_SHIFTS)
+#define IPSEC_BITMAP_LOC_MASK (IPSEC_REDUNDANT_BITS - 1)
+
int
ipsec_chkreplay(u_int32_t seq, struct secasvar *sav)
{
const struct secreplay *replay;
- u_int32_t diff;
- int fr;
- u_int32_t wsizeb; /* Constant: bits of window size. */
- int frlast; /* Constant: last frame. */
+ u_int32_t wsizeb; /* Constant: window size. */
+ int ret, index, bit_location;
IPSEC_ASSERT(sav != NULL, ("Null SA"));
IPSEC_ASSERT(sav->replay != NULL, ("Null replay state"));
+ SECASVAR_LOCK(sav);
+
+ ret = 0;
replay = sav->replay;
+ /* No need to check replay if disabled. */
if (replay->wsize == 0)
- return (1); /* No need to check replay. */
+ goto allowed;
/* Constant. */
- frlast = replay->wsize - 1;
wsizeb = replay->wsize << 3;
/* Sequence number of 0 is invalid. */
if (seq == 0)
- return (0);
+ goto end;
/* First time is always okay. */
if (replay->count == 0)
- return (1);
-
- if (seq > replay->lastseq) {
- /* Larger sequences are okay. */
- return (1);
- } else {
- /* seq is equal or less than lastseq. */
- diff = replay->lastseq - seq;
+ goto allowed;
- /* Over range to check, i.e. too old or wrapped. */
- if (diff >= wsizeb)
- return (0);
-
- fr = frlast - diff / 8;
-
- /* This packet already seen? */
- if ((replay->bitmap)[fr] & (1 << (diff % 8)))
- return (0);
+ /* Larger sequences are okay. */
+ if (seq > replay->lastseq)
+ goto allowed;
+
+ /* Over range to check, i.e. too old or wrapped. */
+ if (replay->lastseq - seq >= wsizeb)
+ goto end;
+
+ /* The sequence is inside the sliding window
+ * now check the bit in the bitmap
+ * bit location only depends on the sequence number
+ */
+ bit_location = seq & IPSEC_BITMAP_LOC_MASK;
+ index = (seq >> IPSEC_REDUNDANT_BIT_SHIFTS)
+ & IPSEC_BITMAP_INDEX_MASK(replay->bitmap_size);
+
+ /* This packet already seen? */
+ if ((replay->bitmap)[index] & (1 << bit_location))
+ goto end;
+
+allowed:
+ ret = 1;
+end:
+ SECASVAR_UNLOCK(sav);
- /* Out of order but good. */
- return (1);
- }
+ return (ret);
}
/*
@@ -1539,72 +1551,61 @@
{
char buf[128];
struct secreplay *replay;
- u_int32_t diff;
- int fr;
- u_int32_t wsizeb; /* Constant: bits of window size. */
- int frlast; /* Constant: last frame. */
+ u_int32_t wsizeb; /* Constant: window size. */
+ int ret, diff, index, bit_location;
IPSEC_ASSERT(sav != NULL, ("Null SA"));
IPSEC_ASSERT(sav->replay != NULL, ("Null replay state"));
+ SECASVAR_LOCK(sav);
+
+ ret = 1;
replay = sav->replay;
if (replay->wsize == 0)
goto ok; /* No need to check replay. */
/* Constant. */
- frlast = replay->wsize - 1;
wsizeb = replay->wsize << 3;
/* Sequence number of 0 is invalid. */
if (seq == 0)
- return (1);
+ goto end;
- /* First time. */
- if (replay->count == 0) {
- replay->lastseq = seq;
- bzero(replay->bitmap, replay->wsize);
- (replay->bitmap)[frlast] = 1;
+ /* The packet is too old, no need to update */
+ if (wsizeb + seq < replay->lastseq)
goto ok;
- }
+ /* Now update the bit */
+ index = (seq >> IPSEC_REDUNDANT_BIT_SHIFTS);
+
+ /* First check if the sequence number is in the range */
if (seq > replay->lastseq) {
- /* seq is larger than lastseq. */
- diff = seq - replay->lastseq;
+ int id;
+ int index_cur = replay->lastseq >> IPSEC_REDUNDANT_BIT_SHIFTS;
- /* New larger sequence number. */
- if (diff < wsizeb) {
- /* In window. */
- /* Set bit for this packet. */
- vshiftl(replay->bitmap, diff, replay->wsize);
- (replay->bitmap)[frlast] |= 1;
- } else {
- /* This packet has a "way larger". */
- bzero(replay->bitmap, replay->wsize);
- (replay->bitmap)[frlast] = 1;
+ diff = index - index_cur;
+ if (diff > replay->bitmap_size) {
+ /* something unusual in this case */
+ diff = replay->bitmap_size;
}
- replay->lastseq = seq;
- /* Larger is good. */
- } else {
- /* seq is equal or less than lastseq. */
- diff = replay->lastseq - seq;
-
- /* Over range to check, i.e. too old or wrapped. */
- if (diff >= wsizeb)
- return (1);
+ for (id = 0; id < diff; ++id) {
+ replay->bitmap[(id + index_cur + 1)
+ & IPSEC_BITMAP_INDEX_MASK(replay->bitmap_size)] = 0;
+ }
- fr = frlast - diff / 8;
+ replay->lastseq = seq;
+ }
- /* This packet already seen? */
- if ((replay->bitmap)[fr] & (1 << (diff % 8)))
- return (1);
+ index &= IPSEC_BITMAP_INDEX_MASK(replay->bitmap_size);
+ bit_location = seq & IPSEC_BITMAP_LOC_MASK;
- /* Mark as seen. */
- (replay->bitmap)[fr] |= (1 << (diff % 8));
+ /* this packet has already been received */
+ if (replay->bitmap[index] & (1 << bit_location))
+ goto end;
- /* Out of order but good. */
- }
+ replay->bitmap[index] |= (1 << bit_location);
ok:
if (replay->count == ~0) {
@@ -1614,39 +1615,18 @@
/* Don't increment, no more packets accepted. */
if ((sav->flags & SADB_X_EXT_CYCSEQ) == 0)
- return (1);
+ goto end;
ipseclog((LOG_WARNING, "%s: replay counter made %d cycle. %s\n",
__func__, replay->overflow,
ipsec_logsastr(sav, buf, sizeof(buf))));
}
- replay->count++;
-
- return (0);
-}
+ ret = 0;
-/*
- * Shift variable length buffer to left.
- * IN: bitmap: pointer to the buffer
- * nbit: the number of to shift.
- * wsize: buffer size (bytes).
- */
-static void
-vshiftl(unsigned char *bitmap, int nbit, int wsize)
-{
- int s, j, i;
- unsigned char over;
-
- for (j = 0; j < nbit; j += 8) {
- s = (nbit - j < 8) ? (nbit - j): 8;
- bitmap[0] <<= s;
- for (i = 1; i < wsize; i++) {
- over = (bitmap[i] >> (8 - s));
- bitmap[i] <<= s;
- bitmap[i-1] |= over;
- }
- }
+end:
+ SECASVAR_UNLOCK(sav);
+ return (ret);
}
/* Return a printable string for the address. */
Index: head/sys/netipsec/key.c
===================================================================
--- head/sys/netipsec/key.c
+++ head/sys/netipsec/key.c
@@ -243,7 +243,10 @@
sizeof(struct sadb_address), /* SADB_X_EXT_NAT_T_OAI */
sizeof(struct sadb_address), /* SADB_X_EXT_NAT_T_OAR */
sizeof(struct sadb_x_nat_t_frag),/* SADB_X_EXT_NAT_T_FRAG */
+ sizeof(struct sadb_x_sa_replay), /* SADB_X_EXT_SA_REPLAY */
};
+_Static_assert(sizeof(minsize)/sizeof(int) == SADB_EXT_MAX + 1, "minsize size mismatch");
+
static const int maxsize[] = {
sizeof(struct sadb_msg), /* SADB_EXT_RESERVED */
sizeof(struct sadb_sa), /* SADB_EXT_SA */
@@ -271,7 +274,9 @@
0, /* SADB_X_EXT_NAT_T_OAI */
0, /* SADB_X_EXT_NAT_T_OAR */
sizeof(struct sadb_x_nat_t_frag),/* SADB_X_EXT_NAT_T_FRAG */
+ sizeof(struct sadb_x_sa_replay), /* SADB_X_EXT_SA_REPLAY */
};
+_Static_assert(sizeof(maxsize)/sizeof(int) == SADB_EXT_MAX + 1, "minsize size mismatch");
static VNET_DEFINE(int, ipsec_esp_keymin) = 256;
static VNET_DEFINE(int, ipsec_esp_auth) = 0;
@@ -472,6 +477,7 @@
#define KEY_PORTTOSADDR(saddr, port) \
key_porttosaddr((struct sockaddr *)(saddr), (port))
static struct mbuf *key_setsadbxsa2(u_int8_t, u_int32_t, u_int32_t);
+static struct mbuf *key_setsadbxsareplay(u_int32_t);
static struct mbuf *key_setsadbxpolicy(u_int16_t, u_int8_t,
u_int32_t, u_int32_t);
static struct seckey *key_dup_keymsg(const struct sadb_key *, u_int,
@@ -2940,6 +2946,8 @@
sav->sched = NULL;
}
if (sav->replay != NULL) {
+ if (sav->replay->bitmap != NULL)
+ free(sav->replay->bitmap, M_IPSEC_MISC);
free(sav->replay, M_IPSEC_MISC);
sav->replay = NULL;
}
@@ -3108,6 +3116,7 @@
/* SA */
if (mhp->ext[SADB_EXT_SA] != NULL) {
const struct sadb_sa *sa0;
+ u_int32_t replay;
sa0 = (const struct sadb_sa *)mhp->ext[SADB_EXT_SA];
if (mhp->extlen[SADB_EXT_SA] < sizeof(*sa0)) {
@@ -3119,19 +3128,57 @@
sav->alg_enc = sa0->sadb_sa_encrypt;
sav->flags = sa0->sadb_sa_flags;
- /* replay window */
- if ((sa0->sadb_sa_flags & SADB_X_EXT_OLD) == 0) {
- sav->replay = (struct secreplay *)
- malloc(sizeof(struct secreplay)+sa0->sadb_sa_replay, M_IPSEC_MISC, M_NOWAIT|M_ZERO);
- if (sav->replay == NULL) {
+ /* Optional replay window */
+ replay = 0;
+ if ((sa0->sadb_sa_flags & SADB_X_EXT_OLD) == 0)
+ replay = sa0->sadb_sa_replay;
+ if ((mhp->ext[SADB_X_EXT_SA_REPLAY]) != NULL) {
+ replay = ((const struct sadb_x_sa_replay *)
+ mhp->ext[SADB_X_EXT_SA_REPLAY])->sadb_x_sa_replay_replay;
+
+ if (replay > UINT32_MAX - 32) {
+ ipseclog((LOG_DEBUG, "%s: replay window too big.\n",
+ __func__));
+ error = EINVAL;
+ goto fail;
+ }
+
+ replay = (replay + 7) >> 3;
+ }
+
+ sav->replay = (struct secreplay *)
+ malloc(sizeof(struct secreplay),
+ M_IPSEC_MISC, M_NOWAIT|M_ZERO);
+ if (sav->replay == NULL) {
+ ipseclog((LOG_DEBUG, "%s: No more memory.\n",
+ __func__));
+ error = ENOBUFS;
+ goto fail;
+ }
+
+ if (replay != 0) {
+ /* number of 32b blocks to be allocated */
+ u_int32_t bitmap_size;
+
+ /* RFC 6479:
+ * - the allocated replay window size must be a power of two
+ * - use an extra 32b block as a redundant window
+ */
+ bitmap_size = 1;
+ while (replay + 4 > bitmap_size)
+ bitmap_size <<= 1;
+ bitmap_size = bitmap_size / 4;
+
+ sav->replay->bitmap = malloc(bitmap_size*sizeof(u_int32_t),
+ M_IPSEC_MISC, M_NOWAIT|M_ZERO);
+ if (sav->replay->bitmap == NULL) {
ipseclog((LOG_DEBUG, "%s: No more memory.\n",
__func__));
error = ENOBUFS;
goto fail;
}
- if (sa0->sadb_sa_replay != 0)
- sav->replay->bitmap = (caddr_t)(sav->replay+1);
- sav->replay->wsize = sa0->sadb_sa_replay;
+ sav->replay->bitmap_size = bitmap_size;
+ sav->replay->wsize = replay;
}
}
@@ -3406,7 +3453,7 @@
struct mbuf *result = NULL, *tres = NULL, *m;
int i;
int dumporder[] = {
- SADB_EXT_SA, SADB_X_EXT_SA2,
+ SADB_EXT_SA, SADB_X_EXT_SA2, SADB_X_EXT_SA_REPLAY,
SADB_EXT_LIFETIME_HARD, SADB_EXT_LIFETIME_SOFT,
SADB_EXT_LIFETIME_CURRENT, SADB_EXT_ADDRESS_SRC,
SADB_EXT_ADDRESS_DST, SADB_EXT_ADDRESS_PROXY, SADB_EXT_KEY_AUTH,
@@ -3419,6 +3466,7 @@
SADB_X_EXT_NAT_T_FRAG,
#endif
};
+ u_int32_t replay_count;
m = key_setsadbmsg(type, 0, satype, seq, pid, sav->refcnt);
if (m == NULL)
@@ -3435,13 +3483,25 @@
break;
case SADB_X_EXT_SA2:
- m = key_setsadbxsa2(sav->sah->saidx.mode,
- sav->replay ? sav->replay->count : 0,
+ SECASVAR_LOCK(sav);
+ replay_count = sav->replay ? sav->replay->count : 0;
+ SECASVAR_UNLOCK(sav);
+ m = key_setsadbxsa2(sav->sah->saidx.mode, replay_count,
sav->sah->saidx.reqid);
if (!m)
goto fail;
break;
+ case SADB_X_EXT_SA_REPLAY:
+ if (sav->replay == NULL ||
+ sav->replay->wsize <= UINT8_MAX)
+ continue;
+
+ m = key_setsadbxsareplay(sav->replay->wsize);
+ if (!m)
+ goto fail;
+ break;
+
case SADB_EXT_ADDRESS_SRC:
m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC,
&sav->sah->saidx.src.sa,
@@ -3634,7 +3694,9 @@
p->sadb_sa_len = PFKEY_UNIT64(len);
p->sadb_sa_exttype = SADB_EXT_SA;
p->sadb_sa_spi = sav->spi;
- p->sadb_sa_replay = (sav->replay != NULL ? sav->replay->wsize : 0);
+ p->sadb_sa_replay = sav->replay ?
+ (sav->replay->wsize > UINT8_MAX ?
+ UINT8_MAX : sav->replay->wsize) : 0;
p->sadb_sa_state = sav->state;
p->sadb_sa_auth = sav->alg_auth;
p->sadb_sa_encrypt = sav->alg_enc;
@@ -3719,6 +3781,32 @@
return m;
}
+/*
+ * Set data into sadb_x_sa_replay.
+ */
+static struct mbuf *
+key_setsadbxsareplay(u_int32_t replay)
+{
+ struct mbuf *m;
+ struct sadb_x_sa_replay *p;
+ size_t len;
+
+ len = PFKEY_ALIGN8(sizeof(struct sadb_x_sa_replay));
+ m = m_get2(len, M_NOWAIT, MT_DATA, 0);
+ if (m == NULL)
+ return (NULL);
+ m_align(m, len);
+ m->m_len = len;
+ p = mtod(m, struct sadb_x_sa_replay *);
+
+ bzero(p, len);
+ p->sadb_x_sa_replay_len = PFKEY_UNIT64(len);
+ p->sadb_x_sa_replay_exttype = SADB_X_EXT_SA_REPLAY;
+ p->sadb_x_sa_replay_replay = (replay << 3);
+
+ return m;
+}
+
#ifdef IPSEC_NAT_T
/*
* Set a type in sadb_x_nat_t_type.
@@ -6853,6 +6941,7 @@
int len;
int error = -1;
struct sadb_lifetime *lt;
+ u_int32_t replay_count;
IPSEC_ASSERT (sav != NULL, ("null sav"));
IPSEC_ASSERT (sav->sah != NULL, ("null sa header"));
@@ -6876,8 +6965,11 @@
m_cat(result, m);
/* create SA extension */
- m = key_setsadbxsa2(sav->sah->saidx.mode,
- sav->replay ? sav->replay->count : 0,
+ SECASVAR_LOCK(sav);
+ replay_count = sav->replay ? sav->replay->count : 0;
+ SECASVAR_UNLOCK(sav);
+
+ m = key_setsadbxsa2(sav->sah->saidx.mode, replay_count,
sav->sah->saidx.reqid);
if (!m) {
error = ENOBUFS;
@@ -6885,6 +6977,15 @@
}
m_cat(result, m);
+ if (sav->replay && sav->replay->wsize > UINT8_MAX) {
+ m = key_setsadbxsareplay(sav->replay->wsize);
+ if (!m) {
+ error = ENOBUFS;
+ goto fail;
+ }
+ m_cat(result, m);
+ }
+
/* create lifetime extension (current and soft) */
len = PFKEY_ALIGN8(sizeof(*lt)) * 2;
m = m_get2(len, M_NOWAIT, MT_DATA, 0);
@@ -7560,6 +7661,7 @@
case SADB_X_EXT_NAT_T_OAR:
case SADB_X_EXT_NAT_T_FRAG:
#endif
+ case SADB_X_EXT_SA_REPLAY:
/* duplicate check */
/*
* XXX Are there duplication payloads of either
Index: head/sys/netipsec/key_debug.c
===================================================================
--- head/sys/netipsec/key_debug.c
+++ head/sys/netipsec/key_debug.c
@@ -570,8 +570,11 @@
if (sav->key_enc != NULL)
kdebug_sadb_key((struct sadb_ext *)sav->key_enc);
- if (sav->replay != NULL)
+ if (sav->replay != NULL) {
+ SECASVAR_LOCK(sav);
kdebug_secreplay(sav->replay);
+ SECASVAR_UNLOCK(sav);
+ }
if (sav->lft_c != NULL)
kdebug_sec_lifetime(sav->lft_c);
if (sav->lft_h != NULL)
@@ -595,8 +598,8 @@
if (rpl == NULL)
panic("%s: NULL pointer was passed.\n", __func__);
- printf(" secreplay{ count=%u wsize=%u seq=%u lastseq=%u",
- rpl->count, rpl->wsize, rpl->seq, rpl->lastseq);
+ printf(" secreplay{ count=%u bitmap_size=%u wsize=%u seq=%u lastseq=%u",
+ rpl->count, rpl->bitmap_size, rpl->wsize, rpl->seq, rpl->lastseq);
if (rpl->bitmap == NULL) {
printf(" }\n");
@@ -605,7 +608,7 @@
printf("\n bitmap { ");
- for (len = 0; len < rpl->wsize; len++) {
+ for (len = 0; len < rpl->bitmap_size*4; len++) {
for (l = 7; l >= 0; l--)
printf("%u", (((rpl->bitmap)[len] >> l) & 1) ? 1 : 0);
}
Index: head/sys/netipsec/keydb.h
===================================================================
--- head/sys/netipsec/keydb.h
+++ head/sys/netipsec/keydb.h
@@ -35,6 +35,8 @@
#ifdef _KERNEL
+#include <sys/mutex.h>
+
#include <netipsec/key_var.h>
#ifndef _SOCKADDR_UNION_DEFINED
@@ -170,14 +172,18 @@
#define SAV_ISCTR(_sav) ((_sav)->alg_enc == SADB_X_EALG_AESCTR)
#define SAV_ISCTRORGCM(_sav) (SAV_ISCTR((_sav)) || SAV_ISGCM((_sav)))
-/* replay prevention */
+/* Replay prevention, protected by SECASVAR_LOCK:
+ * (m) locked by mtx
+ * (c) read only except during creation / free
+ */
struct secreplay {
- u_int32_t count;
- u_int wsize; /* window size, i.g. 4 bytes */
- u_int32_t seq; /* used by sender */
- u_int32_t lastseq; /* used by receiver */
- caddr_t bitmap; /* used by receiver */
- int overflow; /* overflow flag */
+ u_int32_t count; /* (m) */
+ u_int wsize; /* (c) window size, i.g. 4 bytes */
+ u_int32_t seq; /* (m) used by sender */
+ u_int32_t lastseq; /* (m) used by receiver */
+ u_int32_t *bitmap; /* (m) used by receiver */
+ u_int bitmap_size; /* (c) size of the bitmap array */
+ int overflow; /* (m) overflow flag */
};
/* socket table due to send PF_KEY messages. */
Index: head/sys/netipsec/xform_ah.c
===================================================================
--- head/sys/netipsec/xform_ah.c
+++ head/sys/netipsec/xform_ah.c
@@ -961,8 +961,11 @@
/* Insert packet replay counter, as requested. */
if (sav->replay) {
+ SECASVAR_LOCK(sav);
+
if (sav->replay->count == ~0 &&
(sav->flags & SADB_X_EXT_CYCSEQ) == 0) {
+ SECASVAR_UNLOCK(sav);
DPRINTF(("%s: replay counter wrapped for SA %s/%08lx\n",
__func__, ipsec_address(&sav->sah->saidx.dst, buf,
sizeof(buf)), (u_long) ntohl(sav->spi)));
@@ -976,6 +979,8 @@
#endif
sav->replay->count++;
ah->ah_seq = htonl(sav->replay->count);
+
+ SECASVAR_UNLOCK(sav);
}
/* Get crypto descriptors. */
Index: head/sys/netipsec/xform_esp.c
===================================================================
--- head/sys/netipsec/xform_esp.c
+++ head/sys/netipsec/xform_esp.c
@@ -762,12 +762,14 @@
if (sav->replay) {
u_int32_t replay;
+ SECASVAR_LOCK(sav);
#ifdef REGRESSION
/* Emulate replay attack when ipsec_replay is TRUE. */
if (!V_ipsec_replay)
#endif
sav->replay->count++;
replay = htonl(sav->replay->count);
+ SECASVAR_UNLOCK(sav);
bcopy((caddr_t) &replay,
mtod(mo, caddr_t) + roff + sizeof(u_int32_t),
sizeof(u_int32_t));
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Mar 12, 4:25 PM (8 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17122608
Default Alt Text
D8468.diff (19 KB)
Attached To
Mode
D8468: IPSec: support for large replay windows
Attached
Detach File
Event Timeline
Log In to Comment