2020-05-25 15:55:25

by Petr Vaněk

[permalink] [raw]
Subject: [PATCH net-next] xfrm: no-anti-replay protection flag

RFC 4303 in section 3.3.3 suggests to disable anti-replay for manually
distributed ICVs.

This patch introduces new extra_flag XFRM_SA_XFLAG_NO_ANTI_REPLAY which
disables anti-replay for outbound packets if set. The flag is used only
in legacy and bmp code, because esn should not be negotiated if
anti-replay is disabled (see note in 3.3.3 section).

Signed-off-by: Petr Vaněk <[email protected]>
---
include/uapi/linux/xfrm.h | 1 +
net/xfrm/xfrm_replay.c | 12 ++++++++----
2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/include/uapi/linux/xfrm.h b/include/uapi/linux/xfrm.h
index 5f3b9fec7b5f..4842b1ed49e9 100644
--- a/include/uapi/linux/xfrm.h
+++ b/include/uapi/linux/xfrm.h
@@ -387,6 +387,7 @@ struct xfrm_usersa_info {
};

#define XFRM_SA_XFLAG_DONT_ENCAP_DSCP 1
+#define XFRM_SA_XFLAG_NO_ANTI_REPLAY 2

struct xfrm_usersa_id {
xfrm_address_t daddr;
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c
index 98943f8d01aa..1602843aa2ec 100644
--- a/net/xfrm/xfrm_replay.c
+++ b/net/xfrm/xfrm_replay.c
@@ -89,7 +89,8 @@ static int xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb)
if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
XFRM_SKB_CB(skb)->seq.output.low = ++x->replay.oseq;
XFRM_SKB_CB(skb)->seq.output.hi = 0;
- if (unlikely(x->replay.oseq == 0)) {
+ if (unlikely(x->replay.oseq == 0) &&
+ !(x->props.extra_flags & XFRM_SA_XFLAG_NO_ANTI_REPLAY)) {
x->replay.oseq--;
xfrm_audit_state_replay_overflow(x, skb);
err = -EOVERFLOW;
@@ -168,7 +169,8 @@ static int xfrm_replay_overflow_bmp(struct xfrm_state *x, struct sk_buff *skb)
if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
XFRM_SKB_CB(skb)->seq.output.low = ++replay_esn->oseq;
XFRM_SKB_CB(skb)->seq.output.hi = 0;
- if (unlikely(replay_esn->oseq == 0)) {
+ if (unlikely(replay_esn->oseq == 0) &&
+ !(x->props.extra_flags & XFRM_SA_XFLAG_NO_ANTI_REPLAY)) {
replay_esn->oseq--;
xfrm_audit_state_replay_overflow(x, skb);
err = -EOVERFLOW;
@@ -572,7 +574,8 @@ static int xfrm_replay_overflow_offload(struct xfrm_state *x, struct sk_buff *sk

XFRM_SKB_CB(skb)->seq.output.hi = 0;
xo->seq.hi = 0;
- if (unlikely(oseq < x->replay.oseq)) {
+ if (unlikely(oseq < x->replay.oseq) &&
+ !(x->props.extra_flags & XFRM_SA_XFLAG_NO_ANTI_REPLAY)) {
xfrm_audit_state_replay_overflow(x, skb);
err = -EOVERFLOW;

@@ -611,7 +614,8 @@ static int xfrm_replay_overflow_offload_bmp(struct xfrm_state *x, struct sk_buff

XFRM_SKB_CB(skb)->seq.output.hi = 0;
xo->seq.hi = 0;
- if (unlikely(oseq < replay_esn->oseq)) {
+ if (unlikely(oseq < replay_esn->oseq) &&
+ !(x->props.extra_flags & XFRM_SA_XFLAG_NO_ANTI_REPLAY)) {
xfrm_audit_state_replay_overflow(x, skb);
err = -EOVERFLOW;

--
2.26.2


2020-05-27 19:17:57

by Christophe Gouault

[permalink] [raw]
Subject: Re: [PATCH net-next] xfrm: no-anti-replay protection flag

Hi Petr,

This patch is useful, however I think you should change the name of
the option and amend its description:
the option does not disable anti-replay in output (it can only be
disabled in input), it allows the output sequence number to wrap, and
it assumes that the remote peer disabled anti-replay in input.

So you I suggest you change the name of the option to something like
XFRM_SA_XFLAG_OSEQ_MAY_WRAP or XFRM_SA_XFLAG_ALLOW_OSEQ_WRAP.

Best regards,
Christophe


Le lun. 25 mai 2020 à 17:53, Petr Vaněk <[email protected]> a écrit :
>
> RFC 4303 in section 3.3.3 suggests to disable anti-replay for manually
> distributed ICVs.
>
> This patch introduces new extra_flag XFRM_SA_XFLAG_NO_ANTI_REPLAY which
> disables anti-replay for outbound packets if set. The flag is used only
> in legacy and bmp code, because esn should not be negotiated if
> anti-replay is disabled (see note in 3.3.3 section).
>
> Signed-off-by: Petr Vaněk <[email protected]>
> ---
> include/uapi/linux/xfrm.h | 1 +
> net/xfrm/xfrm_replay.c | 12 ++++++++----
> 2 files changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/include/uapi/linux/xfrm.h b/include/uapi/linux/xfrm.h
> index 5f3b9fec7b5f..4842b1ed49e9 100644
> --- a/include/uapi/linux/xfrm.h
> +++ b/include/uapi/linux/xfrm.h
> @@ -387,6 +387,7 @@ struct xfrm_usersa_info {
> };
>
> #define XFRM_SA_XFLAG_DONT_ENCAP_DSCP 1
> +#define XFRM_SA_XFLAG_NO_ANTI_REPLAY 2
>
> struct xfrm_usersa_id {
> xfrm_address_t daddr;
> diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c
> index 98943f8d01aa..1602843aa2ec 100644
> --- a/net/xfrm/xfrm_replay.c
> +++ b/net/xfrm/xfrm_replay.c
> @@ -89,7 +89,8 @@ static int xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb)
> if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
> XFRM_SKB_CB(skb)->seq.output.low = ++x->replay.oseq;
> XFRM_SKB_CB(skb)->seq.output.hi = 0;
> - if (unlikely(x->replay.oseq == 0)) {
> + if (unlikely(x->replay.oseq == 0) &&
> + !(x->props.extra_flags & XFRM_SA_XFLAG_NO_ANTI_REPLAY)) {
> x->replay.oseq--;
> xfrm_audit_state_replay_overflow(x, skb);
> err = -EOVERFLOW;
> @@ -168,7 +169,8 @@ static int xfrm_replay_overflow_bmp(struct xfrm_state *x, struct sk_buff *skb)
> if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
> XFRM_SKB_CB(skb)->seq.output.low = ++replay_esn->oseq;
> XFRM_SKB_CB(skb)->seq.output.hi = 0;
> - if (unlikely(replay_esn->oseq == 0)) {
> + if (unlikely(replay_esn->oseq == 0) &&
> + !(x->props.extra_flags & XFRM_SA_XFLAG_NO_ANTI_REPLAY)) {
> replay_esn->oseq--;
> xfrm_audit_state_replay_overflow(x, skb);
> err = -EOVERFLOW;
> @@ -572,7 +574,8 @@ static int xfrm_replay_overflow_offload(struct xfrm_state *x, struct sk_buff *sk
>
> XFRM_SKB_CB(skb)->seq.output.hi = 0;
> xo->seq.hi = 0;
> - if (unlikely(oseq < x->replay.oseq)) {
> + if (unlikely(oseq < x->replay.oseq) &&
> + !(x->props.extra_flags & XFRM_SA_XFLAG_NO_ANTI_REPLAY)) {
> xfrm_audit_state_replay_overflow(x, skb);
> err = -EOVERFLOW;
>
> @@ -611,7 +614,8 @@ static int xfrm_replay_overflow_offload_bmp(struct xfrm_state *x, struct sk_buff
>
> XFRM_SKB_CB(skb)->seq.output.hi = 0;
> xo->seq.hi = 0;
> - if (unlikely(oseq < replay_esn->oseq)) {
> + if (unlikely(oseq < replay_esn->oseq) &&
> + !(x->props.extra_flags & XFRM_SA_XFLAG_NO_ANTI_REPLAY)) {
> xfrm_audit_state_replay_overflow(x, skb);
> err = -EOVERFLOW;
>
> --
> 2.26.2
>

2020-05-30 12:43:19

by Petr Vaněk

[permalink] [raw]
Subject: Re: [PATCH net-next] xfrm: no-anti-replay protection flag

Hi Christophe,

On Wed, May 27, 2020 at 07:11:21PM +0200, Christophe Gouault wrote:
> This patch is useful, however I think you should change the name of
> the option and amend its description:
> the option does not disable anti-replay in output (it can only be
> disabled in input), it allows the output sequence number to wrap, and
> it assumes that the remote peer disabled anti-replay in input.
>
> So you I suggest you change the name of the option to something like
> XFRM_SA_XFLAG_OSEQ_MAY_WRAP or XFRM_SA_XFLAG_ALLOW_OSEQ_WRAP.

thank you for your suggestions, I changed the patch and sent the second
version.

Petr

2020-05-30 12:48:07

by Petr Vaněk

[permalink] [raw]
Subject: [PATCH net-next v2] xfrm: introduce oseq-may-wrap flag

RFC 4303 in section 3.3.3 suggests to disable anti-replay for manually
distributed ICVs in which case the sender does not need to monitor or
reset the counter. However, the sender still increments the counter and
when it reaches the maximum value, the counter rolls over back to zero.

This patch introduces new extra_flag XFRM_SA_XFLAG_OSEQ_MAY_WRAP which
allows sequence number to cycle in outbound packets if set. This flag is
used only in legacy and bmp code, because esn should not be negotiated
if anti-replay is disabled (see note in 3.3.3 section).

Signed-off-by: Petr Vaněk <[email protected]>
---
include/uapi/linux/xfrm.h | 1 +
net/xfrm/xfrm_replay.c | 12 ++++++++----
2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/include/uapi/linux/xfrm.h b/include/uapi/linux/xfrm.h
index 5f3b9fec7b5f..b701244334b5 100644
--- a/include/uapi/linux/xfrm.h
+++ b/include/uapi/linux/xfrm.h
@@ -387,6 +387,7 @@ struct xfrm_usersa_info {
};

#define XFRM_SA_XFLAG_DONT_ENCAP_DSCP 1
+#define XFRM_SA_XFLAG_OSEQ_MAY_WRAP 2

struct xfrm_usersa_id {
xfrm_address_t daddr;
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c
index 98943f8d01aa..c6a4338a0d08 100644
--- a/net/xfrm/xfrm_replay.c
+++ b/net/xfrm/xfrm_replay.c
@@ -89,7 +89,8 @@ static int xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb)
if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
XFRM_SKB_CB(skb)->seq.output.low = ++x->replay.oseq;
XFRM_SKB_CB(skb)->seq.output.hi = 0;
- if (unlikely(x->replay.oseq == 0)) {
+ if (unlikely(x->replay.oseq == 0) &&
+ !(x->props.extra_flags & XFRM_SA_XFLAG_OSEQ_MAY_WRAP)) {
x->replay.oseq--;
xfrm_audit_state_replay_overflow(x, skb);
err = -EOVERFLOW;
@@ -168,7 +169,8 @@ static int xfrm_replay_overflow_bmp(struct xfrm_state *x, struct sk_buff *skb)
if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
XFRM_SKB_CB(skb)->seq.output.low = ++replay_esn->oseq;
XFRM_SKB_CB(skb)->seq.output.hi = 0;
- if (unlikely(replay_esn->oseq == 0)) {
+ if (unlikely(replay_esn->oseq == 0) &&
+ !(x->props.extra_flags & XFRM_SA_XFLAG_OSEQ_MAY_WRAP)) {
replay_esn->oseq--;
xfrm_audit_state_replay_overflow(x, skb);
err = -EOVERFLOW;
@@ -572,7 +574,8 @@ static int xfrm_replay_overflow_offload(struct xfrm_state *x, struct sk_buff *sk

XFRM_SKB_CB(skb)->seq.output.hi = 0;
xo->seq.hi = 0;
- if (unlikely(oseq < x->replay.oseq)) {
+ if (unlikely(oseq < x->replay.oseq) &&
+ !(x->props.extra_flags & XFRM_SA_XFLAG_OSEQ_MAY_WRAP)) {
xfrm_audit_state_replay_overflow(x, skb);
err = -EOVERFLOW;

@@ -611,7 +614,8 @@ static int xfrm_replay_overflow_offload_bmp(struct xfrm_state *x, struct sk_buff

XFRM_SKB_CB(skb)->seq.output.hi = 0;
xo->seq.hi = 0;
- if (unlikely(oseq < replay_esn->oseq)) {
+ if (unlikely(oseq < replay_esn->oseq) &&
+ !(x->props.extra_flags & XFRM_SA_XFLAG_OSEQ_MAY_WRAP)) {
xfrm_audit_state_replay_overflow(x, skb);
err = -EOVERFLOW;

--
2.26.2

2020-06-02 09:58:09

by Christophe Gouault

[permalink] [raw]
Subject: Re: [PATCH net-next v2] xfrm: introduce oseq-may-wrap flag

Le sam. 30 mai 2020 à 14:39, Petr Vaněk <[email protected]> a écrit :
>
> RFC 4303 in section 3.3.3 suggests to disable anti-replay for manually
> distributed ICVs in which case the sender does not need to monitor or
> reset the counter. However, the sender still increments the counter and
> when it reaches the maximum value, the counter rolls over back to zero.
>
> This patch introduces new extra_flag XFRM_SA_XFLAG_OSEQ_MAY_WRAP which
> allows sequence number to cycle in outbound packets if set. This flag is
> used only in legacy and bmp code, because esn should not be negotiated
> if anti-replay is disabled (see note in 3.3.3 section).
> (...)

Hi Petr,

Thank you for taking my comment into account.
This new patch looks good to me.

Acked-by: Christophe Gouault <[email protected]>

Regards,
Christophe

2020-06-26 05:26:57

by Steffen Klassert

[permalink] [raw]
Subject: Re: [PATCH net-next v2] xfrm: introduce oseq-may-wrap flag

On Sat, May 30, 2020 at 02:39:12PM +0200, Petr Vaněk wrote:
> RFC 4303 in section 3.3.3 suggests to disable anti-replay for manually
> distributed ICVs in which case the sender does not need to monitor or
> reset the counter. However, the sender still increments the counter and
> when it reaches the maximum value, the counter rolls over back to zero.
>
> This patch introduces new extra_flag XFRM_SA_XFLAG_OSEQ_MAY_WRAP which
> allows sequence number to cycle in outbound packets if set. This flag is
> used only in legacy and bmp code, because esn should not be negotiated
> if anti-replay is disabled (see note in 3.3.3 section).
>
> Signed-off-by: Petr Vaněk <[email protected]>

Now applied to ipsec-next, thanks a lot!