Re: [PATCH] xfrm: return error when esp offload is requested and not supported

2021-03-17 Thread Antony Antony
Hi,

On Mon, Mar 15, 2021 at 16:29:59 +0100, Sabrina Dubroca wrote:
> 2021-03-15, 11:43:50 +0100, Steffen Klassert wrote:
> > On Wed, Mar 10, 2021 at 10:36:11AM +0100, Antony Antony wrote:
> > > When ESP offload is not supported by the device return an error,
> > > -EINVAL, instead of silently ignoring it, creating a SA without offload,
> > > and returning success.
> > > 
> > > with this fix ip x s a would return
> > > RTNETLINK answers: Invalid argument
> > > 
> > > Also, return an error, -EINVAL, when CONFIG_XFRM_OFFLOAD is
> > > not defined and the user is trying to create an SA with the offload.
> > > 
> > > Fixes: d77e38e612a0 ("xfrm: Add an IPsec hardware offloading API")
> > > Signed-off-by: Antony Antony 
> > 
> > I feal a bit unease about this one. When we designed the offloading
> > API, we decided to fallback to software if HW offload is not available.

Right! Now, I recollect the silent fallback feature, which was mentioned
when the offload was introduced. However, while using I found it
confusing. And I thought it was an unintended side effect and came up
with a fix. Looking closer at the proposed patch and commit 4a132095dd6 I
wonder what would be a consistent behavior.


> Right, but it's a little bit inconsistent. If HW offload is not
> available, we get silent fallback. This is great for compatibility
> (old kernels will completely ignore the XFRMA_OFFLOAD_DEV attribute,
> new kernels try to emulate this), and because routes can change and
> suddenly the packets that should have been going through some device
> go through another, which may have different capabilities.
> 
> On the other hand, if HW offload is available but doesn't support the
> exact features we're trying to enable (UDP encap, wrong algorithm, etc
> (*)), then we can fail in a visible way.

Yes.

> (*) I know there's an "if (err != -EOPNOTSUPP)" on the result of
> ->xdo_dev_state_add(), but for example mlx5 seems to return EINVAL
> instead of EOPNOTSUPP.

That is interesting. I think !CONFIG_XFRM_OFFLOAD should be
EOPNOTSUPP?

> 
> > Not sure if that was a good idea, but changing this would also change
> > the userspace ABI. So if we change this, we should at least not
> > consider it as a fix because it would be backported to -stable

agreed. It could be a new feature?

> > in that case. Thoughts?
> 
> Agree, but I don't think we could even change this at all.
> 
> At best we could introduce a flag to force offloading, and fail if we
> can't offload. But then what should we do if the traffic for that
> state is rerouted through a different interface, or if offloading is
> temporarily disabled with ethtool? Also, should a kernel with
> !CONFIG_XFRM_OFFLOAD ignore that flag or not?
> 
> Antony, what prompted you to write this patch? Do you have a use case
> for requiring offloading instead of falling back to software?

I was using strongSWAN. Due to NIC changes and route changes the SA,
with offload, failed to create.
Actually, strongSWAN didn't even try to create a SA. It reported an error when 
it checked offload support on the device, after IKE negotiation just before 
installing the SA.

[KNL] 192.168.1.1 is on interface eth2
[KNL] HW offload is not supported by device

To debug I tried "ip x s a eth2" and a the SA got created, which confused me. 
After a closer showed offload was silently ignored.

Next I tried to create an offload to loopback device.
"ip x s a ... offload dev lo dir in" and there was an SA without offload, 
Device lo will never have offload:)
This led me to look at the kernel code. There I found the offload request can 
be silently ignored. So I created a fix.

One important point to note: IKE daemons check for offload support, using 
ETHTOOL_GFEATURES or ETH_SS_FEATURES, before requesting kernel to add a SA with 
offload. I see strongSWAN and libreswan trying to detect it before requesting 
offload. This why I got the error.

I had a closeer look and I noticed that deciding when to fail and when to 
fallback is complex. e.g no NAT support with offload is failure, -EINVAL and 
not a fallback.

I think the current kernel, when it has code to support a feature, should fail 
explictly when the feature requested can't be enabled. While, an older kernel 
which is not aware of the feature may silently ignore an unsupported feature. 
Atleast that is how I feel now!


thanks for the feedback.

-antony


[PATCH] xfrm: return error when esp offload is requested and not supported

2021-03-10 Thread Antony Antony
When ESP offload is not supported by the device return an error,
-EINVAL, instead of silently ignoring it, creating a SA without offload,
and returning success.

with this fix ip x s a would return
RTNETLINK answers: Invalid argument

Also, return an error, -EINVAL, when CONFIG_XFRM_OFFLOAD is
not defined and the user is trying to create an SA with the offload.

Fixes: d77e38e612a0 ("xfrm: Add an IPsec hardware offloading API")
Signed-off-by: Antony Antony 
---
 include/net/xfrm.h | 2 +-
 net/xfrm/xfrm_device.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index bfbc7810df94..05d9f178093c 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1914,7 +1914,7 @@ static inline struct sk_buff *validate_xmit_xfrm(struct 
sk_buff *skb, netdev_fea

 static inline int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, 
struct xfrm_user_offload *xuo)
 {
-   return 0;
+   return -EINVAL;
 }

 static inline void xfrm_dev_state_delete(struct xfrm_state *x)
diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
index edf11893dbe8..1e1a9493c8db 100644
--- a/net/xfrm/xfrm_device.c
+++ b/net/xfrm/xfrm_device.c
@@ -250,7 +250,7 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state 
*x,
if (!dev->xfrmdev_ops || !dev->xfrmdev_ops->xdo_dev_state_add) {
xso->dev = NULL;
dev_put(dev);
-   return 0;
+   return -EINVAL;
}

if (x->props.flags & XFRM_STATE_ESN &&
--
2.20.1



[PATCH ipsec-next v5] xfrm: redact SA secret with lockdown confidentiality

2020-11-17 Thread Antony Antony
redact XFRM SA secret in the netlink response to xfrm_get_sa()
or dumpall sa.
Enable lockdown, confidentiality mode, at boot or at run time.

e.g. when enabled:
cat /sys/kernel/security/lockdown
none integrity [confidentiality]

ip xfrm state
src 172.16.1.200 dst 172.16.1.100
proto esp spi 0x0002 reqid 2 mode tunnel
replay-window 0
aead rfc4106(gcm(aes)) 0x 96

note: the aead secret is redacted.
Redacting secret is also a FIPS 140-2 requirement.

v1->v2
 - add size checks before memset calls
v2->v3
 - replace spaces with tabs for consistency
v3->v4
 - use kernel lockdown instead of a /proc setting
v4->v5
 - remove kconfig option

Reviewed-by: Stephan Mueller 
Signed-off-by: Antony Antony 
---
 include/linux/security.h |  1 +
 net/xfrm/xfrm_user.c | 74 
 security/security.c  |  1 +
 3 files changed, 69 insertions(+), 7 deletions(-)

diff --git a/include/linux/security.h b/include/linux/security.h
index bc2725491560..1112a79a7dba 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -127,6 +127,7 @@ enum lockdown_reason {
LOCKDOWN_PERF,
LOCKDOWN_TRACEFS,
LOCKDOWN_XMON_RW,
+   LOCKDOWN_XFRM_SECRET,
LOCKDOWN_CONFIDENTIALITY_MAX,
 };
 
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index d0c32a8fcc4a..0727ac853b55 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -848,21 +848,84 @@ static int copy_user_offload(struct xfrm_state_offload 
*xso, struct sk_buff *skb
return 0;
 }
 
+static bool xfrm_redact(void)
+{
+   return IS_ENABLED(CONFIG_SECURITY) &&
+   security_locked_down(LOCKDOWN_XFRM_SECRET);
+}
+
 static int copy_to_user_auth(struct xfrm_algo_auth *auth, struct sk_buff *skb)
 {
struct xfrm_algo *algo;
+   struct xfrm_algo_auth *ap;
struct nlattr *nla;
+   bool redact_secret = xfrm_redact();
 
nla = nla_reserve(skb, XFRMA_ALG_AUTH,
  sizeof(*algo) + (auth->alg_key_len + 7) / 8);
if (!nla)
return -EMSGSIZE;
-
algo = nla_data(nla);
strncpy(algo->alg_name, auth->alg_name, sizeof(algo->alg_name));
-   memcpy(algo->alg_key, auth->alg_key, (auth->alg_key_len + 7) / 8);
+
+   if (redact_secret && auth->alg_key_len)
+   memset(algo->alg_key, 0, (auth->alg_key_len + 7) / 8);
+   else
+   memcpy(algo->alg_key, auth->alg_key,
+  (auth->alg_key_len + 7) / 8);
algo->alg_key_len = auth->alg_key_len;
 
+   nla = nla_reserve(skb, XFRMA_ALG_AUTH_TRUNC, xfrm_alg_auth_len(auth));
+   if (!nla)
+   return -EMSGSIZE;
+   ap = nla_data(nla);
+   memcpy(ap, auth, sizeof(struct xfrm_algo_auth));
+   if (redact_secret && auth->alg_key_len)
+   memset(ap->alg_key, 0, (auth->alg_key_len + 7) / 8);
+   else
+   memcpy(ap->alg_key, auth->alg_key,
+  (auth->alg_key_len + 7) / 8);
+   return 0;
+}
+
+static int copy_to_user_aead(struct xfrm_algo_aead *aead, struct sk_buff *skb)
+{
+   struct nlattr *nla = nla_reserve(skb, XFRMA_ALG_AEAD, aead_len(aead));
+   struct xfrm_algo_aead *ap;
+   bool redact_secret = xfrm_redact();
+
+   if (!nla)
+   return -EMSGSIZE;
+
+   ap = nla_data(nla);
+   memcpy(ap, aead, sizeof(*aead));
+
+   if (redact_secret && aead->alg_key_len)
+   memset(ap->alg_key, 0, (aead->alg_key_len + 7) / 8);
+   else
+   memcpy(ap->alg_key, aead->alg_key,
+  (aead->alg_key_len + 7) / 8);
+   return 0;
+}
+
+static int copy_to_user_ealg(struct xfrm_algo *ealg, struct sk_buff *skb)
+{
+   struct xfrm_algo *ap;
+   bool redact_secret = xfrm_redact();
+   struct nlattr *nla = nla_reserve(skb, XFRMA_ALG_CRYPT,
+xfrm_alg_len(ealg));
+   if (!nla)
+   return -EMSGSIZE;
+
+   ap = nla_data(nla);
+   memcpy(ap, ealg, sizeof(*ealg));
+
+   if (redact_secret && ealg->alg_key_len)
+   memset(ap->alg_key, 0, (ealg->alg_key_len + 7) / 8);
+   else
+   memcpy(ap->alg_key, ealg->alg_key,
+  (ealg->alg_key_len + 7) / 8);
+
return 0;
 }
 
@@ -906,20 +969,17 @@ static int copy_to_user_state_extra(struct xfrm_state *x,
goto out;
}
if (x->aead) {
-   ret = nla_put(skb, XFRMA_ALG_AEAD, aead_len(x->aead), x->aead);
+   ret = copy_to_user_aead(x->aead, skb);
if (ret)
goto out;
}
if (x->aalg) {
ret = copy_to_user_auth(x->aalg, skb);
-   if (!

Re: [PATCH] xfrm: redact SA secret with lockdown confidentiality

2020-11-17 Thread Antony Antony
On Sat, Oct 31, 2020 at 11:49:11 +0100, Steffen Klassert wrote:
> On Fri, Oct 16, 2020 at 03:36:12PM +0200, Antony Antony wrote:
> > redact XFRM SA secret in the netlink response to xfrm_get_sa()
> > or dumpall sa.
> > Enable this at build time and set kernel lockdown to confidentiality.
> 
> Wouldn't it be better to enable is at boot or runtime? This defaults
> to 'No' at build time, so distibutions will not compile it in. That
> means that noone who uses a kernel that comes with a Linux distribution
> can use that.

It is a good idea. I will send new version soon.

thanks,
-antony


[PATCH] xfrm: redact SA secret with lockdown confidentiality

2020-10-16 Thread Antony Antony
redact XFRM SA secret in the netlink response to xfrm_get_sa()
or dumpall sa.
Enable this at build time and set kernel lockdown to confidentiality.

e.g.
cat /sys/kernel/security/lockdown
none integrity [confidentiality]

ip xfrm state
src 172.16.1.200 dst 172.16.1.100
proto esp spi 0x0002 reqid 2 mode tunnel
replay-window 0
aead rfc4106(gcm(aes)) 0x 96

note: the aead secret is redacted.
Redacting secret is also a FIPS 140-2 requirement.

v1->v2
 - add size checks before memset calls
v2->v3
 - replace spaces with tabs for consistency
v3->v4
 - use kernel lockdown instead of a /proc setting

Reviewed-by: Stephan Mueller 
Signed-off-by: Antony Antony 
---
 include/linux/security.h |  1 +
 net/xfrm/Kconfig |  9 +
 net/xfrm/xfrm_user.c | 76 
 security/security.c  |  1 +
 4 files changed, 80 insertions(+), 7 deletions(-)

diff --git a/include/linux/security.h b/include/linux/security.h
index 0a0a03b36a3b..8438970473b1 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -126,6 +126,7 @@ enum lockdown_reason {
LOCKDOWN_PERF,
LOCKDOWN_TRACEFS,
LOCKDOWN_XMON_RW,
+   LOCKDOWN_XFRM_SECRET,
LOCKDOWN_CONFIDENTIALITY_MAX,
 };
 
diff --git a/net/xfrm/Kconfig b/net/xfrm/Kconfig
index 5b9a5ab48111..cb592524701d 100644
--- a/net/xfrm/Kconfig
+++ b/net/xfrm/Kconfig
@@ -91,6 +91,15 @@ config XFRM_ESP
select CRYPTO_SEQIV
select CRYPTO_SHA256
 
+config XFRM_REDACT_SECRET
+   bool "Redact xfrm SA secret"
+   depends on XFRM && SECURITY_LOCKDOWN_LSM
+   default n
+   help
+ Redats XFRM SA secret in the netlink message to user space.
+ Redacting secret is also a FIPS 140-2 requirement.
+ e.g. ip xfrm state; will show redacted the SA secret.
+
 config XFRM_IPCOMP
tristate
select XFRM_ALGO
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index fbb7d9d06478..b57599d050dc 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -11,6 +11,7 @@
  *
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -848,21 +849,85 @@ static int copy_user_offload(struct xfrm_state_offload 
*xso, struct sk_buff *skb
return 0;
 }
 
+static bool xfrm_redact(void)
+{
+   return IS_ENABLED(CONFIG_SECURITY) &&
+   IS_ENABLED(CONFIG_XFRM_REDACT_SECRET) &&
+   security_locked_down(LOCKDOWN_XFRM_SECRET);
+}
+
 static int copy_to_user_auth(struct xfrm_algo_auth *auth, struct sk_buff *skb)
 {
struct xfrm_algo *algo;
+   struct xfrm_algo_auth *ap;
struct nlattr *nla;
+   bool redact_secret = xfrm_redact();
 
nla = nla_reserve(skb, XFRMA_ALG_AUTH,
  sizeof(*algo) + (auth->alg_key_len + 7) / 8);
if (!nla)
return -EMSGSIZE;
-
algo = nla_data(nla);
strncpy(algo->alg_name, auth->alg_name, sizeof(algo->alg_name));
-   memcpy(algo->alg_key, auth->alg_key, (auth->alg_key_len + 7) / 8);
+
+   if (redact_secret && auth->alg_key_len)
+   memset(algo->alg_key, 0, (auth->alg_key_len + 7) / 8);
+   else
+   memcpy(algo->alg_key, auth->alg_key,
+  (auth->alg_key_len + 7) / 8);
algo->alg_key_len = auth->alg_key_len;
 
+   nla = nla_reserve(skb, XFRMA_ALG_AUTH_TRUNC, xfrm_alg_auth_len(auth));
+   if (!nla)
+   return -EMSGSIZE;
+   ap = nla_data(nla);
+   memcpy(ap, auth, sizeof(struct xfrm_algo_auth));
+   if (redact_secret && auth->alg_key_len)
+   memset(ap->alg_key, 0, (auth->alg_key_len + 7) / 8);
+   else
+   memcpy(ap->alg_key, auth->alg_key,
+  (auth->alg_key_len + 7) / 8);
+   return 0;
+}
+
+static int copy_to_user_aead(struct xfrm_algo_aead *aead, struct sk_buff *skb)
+{
+   struct nlattr *nla = nla_reserve(skb, XFRMA_ALG_AEAD, aead_len(aead));
+   struct xfrm_algo_aead *ap;
+   bool redact_secret = xfrm_redact();
+
+   if (!nla)
+   return -EMSGSIZE;
+
+   ap = nla_data(nla);
+   memcpy(ap, aead, sizeof(*aead));
+
+   if (redact_secret && aead->alg_key_len)
+   memset(ap->alg_key, 0, (aead->alg_key_len + 7) / 8);
+   else
+   memcpy(ap->alg_key, aead->alg_key,
+  (aead->alg_key_len + 7) / 8);
+   return 0;
+}
+
+static int copy_to_user_ealg(struct xfrm_algo *ealg, struct sk_buff *skb)
+{
+   struct xfrm_algo *ap;
+   bool redact_secret = xfrm_redact();
+   struct nlattr *nla = nla_reserve(skb, XFRMA_ALG_CRYPT,
+xfrm_alg_len(ealg));
+   if (!nla)
+   return -EMSGSIZE;
+
+   ap = nla_data(nla);
+   memcpy(ap, ealg,

[PATCH] ixgbe: fail to create xfrm offload of IPsec tunnel mode SA

2020-10-14 Thread Antony Antony
Based on talks and indirect references ixgbe IPsec offlod do not
support IPsec tunnel mode offload. It can only support IPsec transport
mode offload. Now explicitly fail when creating non transport mode SA
 with offload to avoid false performance expectations.

Fixes: 63a67fe229ea ("ixgbe: add ipsec offload add and remove SA")
Signed-off-by: Antony Antony 
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 5 +
 drivers/net/ethernet/intel/ixgbevf/ipsec.c | 5 +
 2 files changed, 10 insertions(+)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index eca73526ac86..54d47265a7ac 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -575,6 +575,11 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
return -EINVAL;
}
 
+   if (xs->props.mode != XFRM_MODE_TRANSPORT) {
+   netdev_err(dev, "Unsupported mode for ipsec offload\n");
+   return -EINVAL;
+   }
+
if (ixgbe_ipsec_check_mgmt_ip(xs)) {
netdev_err(dev, "IPsec IP addr clash with mgmt filters\n");
return -EINVAL;
diff --git a/drivers/net/ethernet/intel/ixgbevf/ipsec.c 
b/drivers/net/ethernet/intel/ixgbevf/ipsec.c
index 5170dd9d8705..caaea2c920a6 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ipsec.c
@@ -272,6 +272,11 @@ static int ixgbevf_ipsec_add_sa(struct xfrm_state *xs)
return -EINVAL;
}
 
+   if (xs->props.mode != XFRM_MODE_TRANSPORT) {
+   netdev_err(dev, "Unsupported mode for ipsec offload\n");
+   return -EINVAL;
+   }
+
if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) {
struct rx_sa rsa;
 
-- 
2.21.3



[PATCH iproute2-net v2] ip xfrm: support setting XFRMA_SET_MARK_MASK attribute in states

2020-10-02 Thread Antony Antony
The XFRMA_SET_MARK_MASK attribute can be set in states (4.19+)
It is optional and the kernel default is 0x
It is the mask of XFRMA_SET_MARK(a.k.a. XFRMA_OUTPUT_MARK in 4.18)

e.g.
./ip/ip xfrm state add output-mark 0x6 mask 0xab proto esp \
 auth digest_null 0 enc cipher_null ''
ip xfrm state
src 0.0.0.0 dst 0.0.0.0
proto esp spi 0x reqid 0 mode transport
replay-window 0
output-mark 0x6/0xab
auth-trunc digest_null 0x30 0
enc ecb(cipher_null)
anti-replay context: seq 0x0, oseq 0x0, bitmap 0x
sel src 0.0.0.0/0 dst 0.0.0.0/0

Signed-off-by: Antony Antony 
---
 v1 -> v2
  - add man page and usage for mask
--
 ip/xfrm_state.c| 23 ++-
 man/man8/ip-xfrm.8 |  4 +++-
 2 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c
index ddf784ca..a4f452fa 100644
--- a/ip/xfrm_state.c
+++ b/ip/xfrm_state.c
@@ -62,7 +62,7 @@ static void usage(void)
"[ flag FLAG-LIST ] [ sel SELECTOR ] [ LIMIT-LIST ] [ 
encap ENCAP ]\n"
"[ coa ADDR[/PLEN] ] [ ctx CTX ] [ extra-flag 
EXTRA-FLAG-LIST ]\n"
"[ offload [dev DEV] dir DIR ]\n"
-   "[ output-mark OUTPUT-MARK ]\n"
+   "[ output-mark OUTPUT-MARK [ mask MASK ] ]\n"
"[ if_id IF_ID ]\n"
"Usage: ip xfrm state allocspi ID [ mode MODE ] [ mark MARK [ 
mask MASK ] ]\n"
"[ reqid REQID ] [ seq SEQ ] [ min SPI max SPI ]\n"
@@ -328,7 +328,7 @@ static int xfrm_state_modify(int cmd, unsigned int flags, 
int argc, char **argv)
struct xfrm_user_sec_ctx sctx;
charstr[CTX_BUF_SIZE];
} ctx = {};
-   __u32 output_mark = 0;
+   struct xfrm_mark output_mark = {0, 0};
bool is_if_id_set = false;
__u32 if_id = 0;
 
@@ -448,8 +448,18 @@ static int xfrm_state_modify(int cmd, unsigned int flags, 
int argc, char **argv)
}
} else if (strcmp(*argv, "output-mark") == 0) {
NEXT_ARG();
-   if (get_u32(&output_mark, *argv, 0))
+   if (get_u32(&output_mark.v, *argv, 0))
invarg("value after \"output-mark\" is 
invalid", *argv);
+   if (argc > 1) {
+   NEXT_ARG();
+   if (strcmp(*argv, "mask") == 0) {
+   NEXT_ARG();
+   if (get_u32(&output_mark.m, *argv, 0))
+   invarg("mask value is 
invalid\n", *argv);
+   } else {
+   PREV_ARG();
+   }
+   }
} else if (strcmp(*argv, "if_id") == 0) {
NEXT_ARG();
if (get_u32(&if_id, *argv, 0))
@@ -741,8 +751,11 @@ static int xfrm_state_modify(int cmd, unsigned int flags, 
int argc, char **argv)
}
}
 
-   if (output_mark)
-   addattr32(&req.n, sizeof(req.buf), XFRMA_OUTPUT_MARK, 
output_mark);
+   if (output_mark.v)
+   addattr32(&req.n, sizeof(req.buf), XFRMA_OUTPUT_MARK, 
output_mark.v);
+
+   if (output_mark.m)
+   addattr32(&req.n, sizeof(req.buf), XFRMA_SET_MARK_MASK, 
output_mark.m);
 
if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
exit(1);
diff --git a/man/man8/ip-xfrm.8 b/man/man8/ip-xfrm.8
index 4fa31651..2669b386 100644
--- a/man/man8/ip-xfrm.8
+++ b/man/man8/ip-xfrm.8
@@ -60,7 +60,9 @@ ip-xfrm \- transform configuration
 .RB "[ " extra-flag
 .IR EXTRA-FLAG-LIST " ]"
 .RB "[ " output-mark
-.IR OUTPUT-MARK " ]"
+.IR OUTPUT-MARK
+.RB "[ " mask
+.IR MASK " ] ]"
 .RB "[ " if_id
 .IR IF-ID " ]"
 
-- 
2.21.3



[PATCH iproute2-next] ip xfrm: support setting XFRMA_SET_MARK_MASK attribute in states

2020-09-29 Thread Antony Antony
The XFRMA_SET_MARK_MASK attribute can be set in states (4.19+)
It is optional and the kernel default is 0x
It is the mask of XFRMA_SET_MARK(a.k.a. XFRMA_OUTPUT_MARK in 4.18)

e.g.
./ip/ip xfrm state add output-mark 0x6 mask 0xab proto esp \
 auth digest_null 0 enc cipher_null ''
ip xfrm state
src 0.0.0.0 dst 0.0.0.0
proto esp spi 0x reqid 0 mode transport
replay-window 0
output-mark 0x6/0xab
auth-trunc digest_null 0x30 0
enc ecb(cipher_null)
anti-replay context: seq 0x0, oseq 0x0, bitmap 0x
sel src 0.0.0.0/0 dst 0.0.0.0/0

Signed-off-by: Antony Antony 
---
 ip/xfrm_state.c | 21 +
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c
index ddf784ca..779ccf0e 100644
--- a/ip/xfrm_state.c
+++ b/ip/xfrm_state.c
@@ -328,7 +328,7 @@ static int xfrm_state_modify(int cmd, unsigned int flags, 
int argc, char **argv)
struct xfrm_user_sec_ctx sctx;
charstr[CTX_BUF_SIZE];
} ctx = {};
-   __u32 output_mark = 0;
+   struct xfrm_mark output_mark = {0, 0};
bool is_if_id_set = false;
__u32 if_id = 0;
 
@@ -448,8 +448,18 @@ static int xfrm_state_modify(int cmd, unsigned int flags, 
int argc, char **argv)
}
} else if (strcmp(*argv, "output-mark") == 0) {
NEXT_ARG();
-   if (get_u32(&output_mark, *argv, 0))
+   if (get_u32(&output_mark.v, *argv, 0))
invarg("value after \"output-mark\" is 
invalid", *argv);
+   if (argc > 1) {
+   NEXT_ARG();
+   if (strcmp(*argv, "mask") == 0) {
+   NEXT_ARG();
+   if (get_u32(&output_mark.m, *argv, 0))
+   invarg("mask value is 
invalid\n", *argv);
+   } else {
+   PREV_ARG();
+   }
+   }
} else if (strcmp(*argv, "if_id") == 0) {
NEXT_ARG();
if (get_u32(&if_id, *argv, 0))
@@ -741,8 +751,11 @@ static int xfrm_state_modify(int cmd, unsigned int flags, 
int argc, char **argv)
}
}
 
-   if (output_mark)
-   addattr32(&req.n, sizeof(req.buf), XFRMA_OUTPUT_MARK, 
output_mark);
+   if (output_mark.v)
+   addattr32(&req.n, sizeof(req.buf), XFRMA_OUTPUT_MARK, 
output_mark.v);
+
+   if (output_mark.m)
+   addattr32(&req.n, sizeof(req.buf), XFRMA_SET_MARK_MASK, 
output_mark.m);
 
if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
exit(1);
-- 
2.21.3



[PATCH iproute2-next RFC] ip xfrm: support setting XFRMA_SET_MARK_MASK attribute in states

2020-09-19 Thread Antony Antony
The XFRMA_SET_MARK_MASK attribute can be set in states (4.19+)
It is the mask of XFRMA_SET_MARK(a.k.a. XFRMA_OUTPUT_MARK in 4.18)
It is optional and the kernel default is 0x

e.g.
./ip/ip xfrm state add output-mark 0x6 mask 0xab proto esp \
 auth digest_null 0 enc cipher_null ''
ip xfrm state
src 0.0.0.0 dst 0.0.0.0
proto esp spi 0x reqid 0 mode transport
replay-window 0
output-mark 0x6/0xab
auth-trunc digest_null 0x30 0
enc ecb(cipher_null)
anti-replay context: seq 0x0, oseq 0x0, bitmap 0x
sel src 0.0.0.0/0 dst 0.0.0.0/0

NOTE: a disadavantage of this version: error message would be the same
for the option 'mark' and  'output-mark'
e.g
./ip/ip xfrm state add output-mark 0xZZ mask 0xab proto \
 esp auth digest_null 0 enc cipher_null ''
Error: argument "0xZZ" is wrong: MARK value is invalid

./ip/ip xfrm state add mark 0xZZ mask 0xab proto esp auth \
 digest_null 0 enc cipher_null ''
Error: argument "0xZZ" is wrong: MARK value is invalid

Signed-off-by: Antony Antony 
---
 ip/xfrm_state.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c
index ddf784ca..a258a1a5 100644
--- a/ip/xfrm_state.c
+++ b/ip/xfrm_state.c
@@ -328,7 +328,7 @@ static int xfrm_state_modify(int cmd, unsigned int flags, 
int argc, char **argv)
struct xfrm_user_sec_ctx sctx;
charstr[CTX_BUF_SIZE];
} ctx = {};
-   __u32 output_mark = 0;
+   struct xfrm_mark output_mark = {0, 0};
bool is_if_id_set = false;
__u32 if_id = 0;
 
@@ -447,9 +447,7 @@ static int xfrm_state_modify(int cmd, unsigned int flags, 
int argc, char **argv)
is_offload = false;
}
} else if (strcmp(*argv, "output-mark") == 0) {
-   NEXT_ARG();
-   if (get_u32(&output_mark, *argv, 0))
-   invarg("value after \"output-mark\" is 
invalid", *argv);
+   xfrm_parse_mark(&output_mark, &argc, &argv);
} else if (strcmp(*argv, "if_id") == 0) {
NEXT_ARG();
if (get_u32(&if_id, *argv, 0))
@@ -741,8 +739,11 @@ static int xfrm_state_modify(int cmd, unsigned int flags, 
int argc, char **argv)
}
}
 
-   if (output_mark)
-   addattr32(&req.n, sizeof(req.buf), XFRMA_OUTPUT_MARK, 
output_mark);
+   if (output_mark.v)
+   addattr32(&req.n, sizeof(req.buf), XFRMA_OUTPUT_MARK, 
output_mark.v);
+   if (output_mark.m)
+   addattr32(&req.n, sizeof(req.buf), XFRMA_SET_MARK_MASK,
+ output_mark.m);
 
if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
exit(1);
-- 
2.21.3



[PATCH iproute2-next RFC] ip xfrm: support setting XFRMA_SET_MARK_MASK attribute in states

2020-09-19 Thread Antony Antony
The XFRMA_SET_MARK_MASK attribute can be set in states (4.19+)
It is optional and the kernel default is 0x
It is the mask of XFRMA_SET_MARK(a.k.a. XFRMA_OUTPUT_MARK in 4.18)

e.g.
./ip/ip xfrm state add output-mark 0x6 mask 0xab proto esp \
 auth digest_null 0 enc cipher_null ''
ip xfrm state
src 0.0.0.0 dst 0.0.0.0
proto esp spi 0x reqid 0 mode transport
replay-window 0
output-mark 0x6/0xab
auth-trunc digest_null 0x30 0
enc ecb(cipher_null)
anti-replay context: seq 0x0, oseq 0x0, bitmap 0x
sel src 0.0.0.0/0 dst 0.0.0.0/0

NOTE: I am sending two versions. Is there preference for the next one
over this? A diference is in error message for "mark" and "output-mark"

./ip/ip xfrm state add output-mark 0xZZ mask 0xab proto esp \
 auth digest_null 0 enc cipher_null ''
Error: argument "0xZZ" is wrong: value after "output-mark" is invalid

vs

./ip/ip xfrm state add mark 0xZZ mask 0xab proto esp \
 auth digest_null 0 enc cipher_null ''
Error: argument "0xZZ" is wrong: MARK value is invalid

Signed-off-by: Antony Antony 
---
 ip/xfrm_state.c | 22 +-
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c
index ddf784ca..c45d993b 100644
--- a/ip/xfrm_state.c
+++ b/ip/xfrm_state.c
@@ -328,7 +328,7 @@ static int xfrm_state_modify(int cmd, unsigned int flags, 
int argc, char **argv)
struct xfrm_user_sec_ctx sctx;
charstr[CTX_BUF_SIZE];
} ctx = {};
-   __u32 output_mark = 0;
+   struct xfrm_mark output_mark = {0, 0};
bool is_if_id_set = false;
__u32 if_id = 0;
 
@@ -403,7 +403,6 @@ static int xfrm_state_modify(int cmd, unsigned int flags, 
int argc, char **argv)
coap = *argv;
 
NEXT_ARG();
-
get_prefix(&coa, *argv, preferred_family);
if (coa.family == AF_UNSPEC)
invarg("value after \"coa\" has an unrecognized 
address family", *argv);
@@ -448,8 +447,18 @@ static int xfrm_state_modify(int cmd, unsigned int flags, 
int argc, char **argv)
}
} else if (strcmp(*argv, "output-mark") == 0) {
NEXT_ARG();
-   if (get_u32(&output_mark, *argv, 0))
+   if (get_u32(&output_mark.v, *argv, 0))
invarg("value after \"output-mark\" is 
invalid", *argv);
+   if (argc > 1) {
+   NEXT_ARG();
+   if (strcmp(*argv, "mask") == 0) {
+   NEXT_ARG();
+   if (get_u32(&output_mark.m, *argv, 0))
+   invarg("mask value is 
invalid\n", *argv);
+   } else {
+   PREV_ARG();
+   }
+   }
} else if (strcmp(*argv, "if_id") == 0) {
NEXT_ARG();
if (get_u32(&if_id, *argv, 0))
@@ -741,8 +750,11 @@ static int xfrm_state_modify(int cmd, unsigned int flags, 
int argc, char **argv)
}
}
 
-   if (output_mark)
-   addattr32(&req.n, sizeof(req.buf), XFRMA_OUTPUT_MARK, 
output_mark);
+   if (output_mark.v)
+   addattr32(&req.n, sizeof(req.buf), XFRMA_OUTPUT_MARK, 
output_mark.v);
+
+   if (output_mark.m)
+   addattr32(&req.n, sizeof(req.buf), XFRMA_SET_MARK_MASK, 
output_mark.m);
 
if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
exit(1);
-- 
2.21.3



[PATCH v3 4/4] xfrm: clone whole liftime_cur structure in xfrm_do_migrate

2020-09-03 Thread Antony Antony
When we clone state only add_time was cloned. It missed values like
bytes, packets.  Now clone the all members of the structure.

v1->v3:
 - use memcpy to copy the entire structure

Fixes: 80c9abaabf42 ("[XFRM]: Extension for dynamic update of endpoint 
address(es)")
Signed-off-by: Antony Antony 
---
 net/xfrm/xfrm_state.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 5e5ed8108498..5ff392e6f3c1 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1550,7 +1550,7 @@ static struct xfrm_state *xfrm_state_clone(struct 
xfrm_state *orig,
x->tfcpad = orig->tfcpad;
x->replay_maxdiff = orig->replay_maxdiff;
x->replay_maxage = orig->replay_maxage;
-   x->curlft.add_time = orig->curlft.add_time;
+   memcpy(&x->curlft, &orig->curlft, sizeof(x->curlft));
x->km.state = orig->km.state;
x->km.seq = orig->km.seq;
x->replay = orig->replay;
-- 
2.20.1



[PATCH v3 3/4] xfrm: clone XFRMA_SEC_CTX in xfrm_do_migrate

2020-09-03 Thread Antony Antony
XFRMA_SEC_CTX was not cloned from the old to the new.
Migrate this attribute during XFRMA_MSG_MIGRATE

v1->v2:
 - return -ENOMEM on error
v2->v3:
 - fix return type to int

Fixes: 80c9abaabf42 ("[XFRM]: Extension for dynamic update of endpoint 
address(es)")
Signed-off-by: Antony Antony 
---
 net/xfrm/xfrm_state.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 3a000f289dcd..5e5ed8108498 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1441,6 +1441,30 @@ int xfrm_state_add(struct xfrm_state *x)
 EXPORT_SYMBOL(xfrm_state_add);
 
 #ifdef CONFIG_XFRM_MIGRATE
+static inline int clone_security(struct xfrm_state *x, struct xfrm_sec_ctx 
*security)
+{
+   struct xfrm_user_sec_ctx *uctx;
+   int size = sizeof(*uctx) + security->ctx_len;
+   int err;
+
+   uctx = kmalloc(size, GFP_KERNEL);
+   if (!uctx)
+   return -ENOMEM;
+
+   uctx->exttype = XFRMA_SEC_CTX;
+   uctx->len = size;
+   uctx->ctx_doi = security->ctx_doi;
+   uctx->ctx_alg = security->ctx_alg;
+   uctx->ctx_len = security->ctx_len;
+   memcpy(uctx + 1, security->ctx_str, security->ctx_len);
+   err = security_xfrm_state_alloc(x, uctx);
+   kfree(uctx);
+   if (err)
+   return err;
+
+   return 0;
+}
+
 static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
   struct xfrm_encap_tmpl *encap)
 {
@@ -1497,6 +1521,10 @@ static struct xfrm_state *xfrm_state_clone(struct 
xfrm_state *orig,
goto error;
}
 
+   if (orig->security)
+   if (clone_security(x, orig->security))
+   goto error;
+
if (orig->coaddr) {
x->coaddr = kmemdup(orig->coaddr, sizeof(*x->coaddr),
GFP_KERNEL);
-- 
2.20.1



[PATCH v3 2/4] xfrm: clone XFRMA_REPLAY_ESN_VAL in xfrm_do_migrate

2020-09-03 Thread Antony Antony
XFRMA_REPLAY_ESN_VAL was not cloned completely from the old to the new.
Migrate this attribute during XFRMA_MSG_MIGRATE

v1->v2:
 - move curleft cloning to a separate patch

Fixes: af2f464e326e ("xfrm: Assign esn pointers when cloning a state")
Signed-off-by: Antony Antony 
---
 include/net/xfrm.h | 16 ++--
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 2737d24ec244..9e806c781025 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1773,21 +1773,17 @@ static inline unsigned int 
xfrm_replay_state_esn_len(struct xfrm_replay_state_es
 static inline int xfrm_replay_clone(struct xfrm_state *x,
 struct xfrm_state *orig)
 {
-   x->replay_esn = kzalloc(xfrm_replay_state_esn_len(orig->replay_esn),
+
+   x->replay_esn = kmemdup(orig->replay_esn,
+   xfrm_replay_state_esn_len(orig->replay_esn),
GFP_KERNEL);
if (!x->replay_esn)
return -ENOMEM;
-
-   x->replay_esn->bmp_len = orig->replay_esn->bmp_len;
-   x->replay_esn->replay_window = orig->replay_esn->replay_window;
-
-   x->preplay_esn = kmemdup(x->replay_esn,
-xfrm_replay_state_esn_len(x->replay_esn),
+   x->preplay_esn = kmemdup(orig->preplay_esn,
+xfrm_replay_state_esn_len(orig->preplay_esn),
 GFP_KERNEL);
-   if (!x->preplay_esn) {
-   kfree(x->replay_esn);
+   if (!x->preplay_esn)
return -ENOMEM;
-   }
 
return 0;
 }
-- 
2.20.1



[PATCH v3 1/4] xfrm: clone XFRMA_SET_MARK in xfrm_do_migrate

2020-09-03 Thread Antony Antony
XFRMA_SET_MARK and XFRMA_SET_MARK_MASK was not cloned from the old
to the new. Migrate these two attributes during XFRMA_MSG_MIGRATE

Fixes: 9b42c1f179a6 ("xfrm: Extend the output_mark to support input direction 
and masking.")
Signed-off-by: Antony Antony 
---
 net/xfrm/xfrm_state.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 69520ad3d83b..3a000f289dcd 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1510,6 +1510,7 @@ static struct xfrm_state *xfrm_state_clone(struct 
xfrm_state *orig,
}
 
memcpy(&x->mark, &orig->mark, sizeof(x->mark));
+   memcpy(&x->props.smark, &orig->props.smark, sizeof(x->props.smark));
 
if (xfrm_init_state(x) < 0)
goto error;
-- 
2.20.1



[PATCH iproute2-next] ip xfrm: support printing XFRMA_SET_MARK_MASK attribute in states

2020-08-28 Thread Antony Antony
The XFRMA_SET_MARK_MASK attribute is set in states (4.19+).
It is the mask of XFRMA_SET_MARK(a.k.a. XFRMA_OUTPUT_MARK in 4.18)

sample output: note the output-mark mask
ip xfrm state
src 192.1.2.23 dst 192.1.3.33
proto esp spi 0xSPISPI reqid REQID mode tunnel
replay-window 32 flag af-unspec
output-mark 0x3/0xff
aead rfc4106(gcm(aes)) 0xENCAUTHKEY 128
if_id 0x1

Signed-off-by: Antony Antony 
---
 ip/ipxfrm.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/ip/ipxfrm.c b/ip/ipxfrm.c
index cac8ba25..e4a72bd0 100644
--- a/ip/ipxfrm.c
+++ b/ip/ipxfrm.c
@@ -649,6 +649,10 @@ static void xfrm_output_mark_print(struct rtattr *tb[], 
FILE *fp)
__u32 output_mark = rta_getattr_u32(tb[XFRMA_OUTPUT_MARK]);
 
fprintf(fp, "output-mark 0x%x", output_mark);
+   if (tb[XFRMA_SET_MARK_MASK]) {
+   __u32 mask = rta_getattr_u32(tb[XFRMA_SET_MARK_MASK]);
+   fprintf(fp, "/0x%x", mask);
+   }
 }
 
 int xfrm_parse_mark(struct xfrm_mark *mark, int *argcp, char ***argvp)
-- 
2.21.3



[PATCH RFC] xfrm: fail to create ixgbe offload of IPsec tunnel mode sa

2020-08-28 Thread Antony Antony
Based on talks and indirect references ixgbe driver does not
support offloading IPsec tunnel mode. It only support transport mode.
Now explicitly fail to avoid when trying to offload.

Fixes: 63a67fe229ea ("ixgbe: add ipsec offload add and remove SA")
Signed-off-by: Antony Antony 
---
I haven't tested this fix as I have no access to the hardware.
This patch is based on a libreswan bug report.
https://github.com/libreswan/libreswan/issues/252
Is it useful to this bug report in kernel commit message?

 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 5 +
 drivers/net/ethernet/intel/ixgbevf/ipsec.c | 5 +
 2 files changed, 10 insertions(+)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index eca73526ac86..e2b978efcc5a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -575,6 +575,11 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
return -EINVAL;
}
 
+   if (xs->props.mode != XFRM_MODE_TRANSPORT) {
+   netdev_err(dev, "Unsupported mode for ipsec offload\n");
+   return -EINVAL;
+   }
+
if (ixgbe_ipsec_check_mgmt_ip(xs)) {
netdev_err(dev, "IPsec IP addr clash with mgmt filters\n");
return -EINVAL;
diff --git a/drivers/net/ethernet/intel/ixgbevf/ipsec.c 
b/drivers/net/ethernet/intel/ixgbevf/ipsec.c
index 5170dd9d8705..d11b3f3414ea 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ipsec.c
@@ -272,6 +272,11 @@ static int ixgbevf_ipsec_add_sa(struct xfrm_state *xs)
return -EINVAL;
}
 
+   if (xs->props.mode != XFRM_MODE_TRANSPORT) {
+   netdev_err(dev, "Unsupported mode for ipsec offload\n");
+   return -EINVAL;
+   }
+
if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) {
struct rx_sa rsa;
 
-- 
2.21.3



Re: [PATCH ipsec-next v3] xfrm: add /proc/sys/core/net/xfrm_redact_secret

2020-08-27 Thread Antony Antony
Hi David,

On Mon, Aug 24, 2020 at 08:00:38 +0200, Antony Antony wrote:
> On Thu, Aug 20, 2020 at 15:42:22 -0700, David Miller wrote:
> > From: Antony Antony 
> > Date: Thu, 20 Aug 2020 20:35:49 +0200
> > 
> > > Redacting secret is a FIPS 140-2 requirement.
> > 
> > Why not control this via the kernel lockdown mode rather than making
> > an ad-hoc API for this? 
> 
> Let me try to use kernel lockdown mode. thanks for the idea. 
> 
> From a quick googling I guess it would be part of "lockdown= confidentiality".
> I wonder if kernel lockdown would allow disabling just this one feature 
> independent of other lockdowns.

I looked at kernel lockdown mode code and documentation. I am thinking 
xfrm_redact is probably not a kernel lockdown mode feature. There is no kernel 
lockdown setting per net namespace.

During an initial discussions of xfrm_redact we thought per namespace would be 
useful in some use cases.

If there is a way to set lockdown per net namespace it would be better than 
/proc/sys/core/net/xfrm_redact_secret.


[PATCH v2 4/4] xfrm: clone whole liftime_cur structure in xfrm_do_migrate

2020-08-26 Thread Antony Antony
When we clone state only add_time was cloned. It missed values like
bytes, packets.  Now clone the all members of the structure.

Fixes: 80c9abaabf42 ("[XFRM]: Extension for dynamic update of endpoint 
address(es)")
Signed-off-by: Antony Antony 
---
 net/xfrm/xfrm_state.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 16988303aed6..64eb4a6fcfc2 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1550,7 +1550,7 @@ static struct xfrm_state *xfrm_state_clone(struct 
xfrm_state *orig,
x->tfcpad = orig->tfcpad;
x->replay_maxdiff = orig->replay_maxdiff;
x->replay_maxage = orig->replay_maxage;
-   x->curlft.add_time = orig->curlft.add_time;
+   x->curlft = orig->curlft;
x->km.state = orig->km.state;
x->km.seq = orig->km.seq;
x->replay = orig->replay;
-- 
2.20.1



[PATCH v2 3/4] xfrm: clone XFRMA_SEC_CTX in xfrm_do_migrate

2020-08-26 Thread Antony Antony
XFRMA_SEC_CTX was not cloned from the old to the new.
Migrate this attribute during XFRMA_MSG_MIGRATE

v1->v2:
 - return -ENOMEM on error

Fixes: 80c9abaabf42 ("[XFRM]: Extension for dynamic update of endpoint 
address(es)")
Signed-off-by: Antony Antony 
---
 net/xfrm/xfrm_state.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 3a000f289dcd..16988303aed6 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1441,6 +1441,30 @@ int xfrm_state_add(struct xfrm_state *x)
 EXPORT_SYMBOL(xfrm_state_add);
 
 #ifdef CONFIG_XFRM_MIGRATE
+static inline bool clone_security(struct xfrm_state *x, struct xfrm_sec_ctx 
*security)
+{
+   struct xfrm_user_sec_ctx *uctx;
+   int size = sizeof(*uctx) + security->ctx_len;
+   int err;
+
+   uctx = kmalloc(size, GFP_KERNEL);
+   if (!uctx)
+   return -ENOMEM;
+
+   uctx->exttype = XFRMA_SEC_CTX;
+   uctx->len = size;
+   uctx->ctx_doi = security->ctx_doi;
+   uctx->ctx_alg = security->ctx_alg;
+   uctx->ctx_len = security->ctx_len;
+   memcpy(uctx + 1, security->ctx_str, security->ctx_len);
+   err = security_xfrm_state_alloc(x, uctx);
+   kfree(uctx);
+   if (err)
+   return err;
+
+   return 0;
+}
+
 static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
   struct xfrm_encap_tmpl *encap)
 {
@@ -1497,6 +1521,10 @@ static struct xfrm_state *xfrm_state_clone(struct 
xfrm_state *orig,
goto error;
}
 
+   if (orig->security)
+   if (clone_security(x, orig->security))
+   goto error;
+
if (orig->coaddr) {
x->coaddr = kmemdup(orig->coaddr, sizeof(*x->coaddr),
GFP_KERNEL);
-- 
2.20.1



[PATCH v2 2/4] xfrm: clone XFRMA_REPLAY_ESN_VAL in xfrm_do_migrate

2020-08-26 Thread Antony Antony
XFRMA_REPLAY_ESN_VAL was not cloned completely from the old to the new.
Migrate this attribute during XFRMA_MSG_MIGRATE

v1->v2:
 - move curleft cloning to a seperate patch

Fixes: af2f464e326e ("xfrm: Assign esn pointers when cloning a state")
Signed-off-by: Antony Antony 
---
 include/net/xfrm.h | 16 ++--
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 2737d24ec244..9e806c781025 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1773,21 +1773,17 @@ static inline unsigned int 
xfrm_replay_state_esn_len(struct xfrm_replay_state_es
 static inline int xfrm_replay_clone(struct xfrm_state *x,
 struct xfrm_state *orig)
 {
-   x->replay_esn = kzalloc(xfrm_replay_state_esn_len(orig->replay_esn),
+
+   x->replay_esn = kmemdup(orig->replay_esn,
+   xfrm_replay_state_esn_len(orig->replay_esn),
GFP_KERNEL);
if (!x->replay_esn)
return -ENOMEM;
-
-   x->replay_esn->bmp_len = orig->replay_esn->bmp_len;
-   x->replay_esn->replay_window = orig->replay_esn->replay_window;
-
-   x->preplay_esn = kmemdup(x->replay_esn,
-xfrm_replay_state_esn_len(x->replay_esn),
+   x->preplay_esn = kmemdup(orig->preplay_esn,
+xfrm_replay_state_esn_len(orig->preplay_esn),
 GFP_KERNEL);
-   if (!x->preplay_esn) {
-   kfree(x->replay_esn);
+   if (!x->preplay_esn)
return -ENOMEM;
-   }
 
return 0;
 }
-- 
2.20.1



[PATCH v2 1/4] xfrm: clone XFRMA_SET_MARK in xfrm_do_migrate

2020-08-26 Thread Antony Antony
XFRMA_SET_MARK and XFRMA_SET_MARK_MASK was not cloned from the old
to the new. Migrate these two attributes during XFRMA_MSG_MIGRATE

Fixes: 9b42c1f179a6 ("xfrm: Extend the output_mark to support input direction 
and masking.")
Signed-off-by: Antony Antony 
---
 net/xfrm/xfrm_state.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 69520ad3d83b..3a000f289dcd 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1510,6 +1510,7 @@ static struct xfrm_state *xfrm_state_clone(struct 
xfrm_state *orig,
}
 
memcpy(&x->mark, &orig->mark, sizeof(x->mark));
+   memcpy(&x->props.smark, &orig->props.smark, sizeof(x->props.smark));
 
if (xfrm_init_state(x) < 0)
goto error;
-- 
2.20.1



Re: [PATCH ipsec-next v3] xfrm: add /proc/sys/core/net/xfrm_redact_secret

2020-08-23 Thread Antony Antony
On Thu, Aug 20, 2020 at 15:42:22 -0700, David Miller wrote:
> From: Antony Antony 
> Date: Thu, 20 Aug 2020 20:35:49 +0200
> 
> > Redacting secret is a FIPS 140-2 requirement.
> 
> Why not control this via the kernel lockdown mode rather than making
> an ad-hoc API for this? 

Let me try to use kernel lockdown mode. thanks for the idea. 

>From a quick googling I guess it would be part of "lockdown= confidentiality".
I wonder if kernel lockdown would allow disabling just this one feature 
independent of other lockdowns.

-antony


[PATCH ipsec-next v3] xfrm: add /proc/sys/core/net/xfrm_redact_secret

2020-08-20 Thread Antony Antony
when enabled, 1, redact XFRM SA secret in the netlink response to
xfrm_get_sa() or dump all sa.

e.g
echo 1 > /proc/sys/net/core/xfrm_redact_secret
ip xfrm state
src 172.16.1.200 dst 172.16.1.100
proto esp spi 0x0002 reqid 2 mode tunnel
replay-window 0
aead rfc4106(gcm(aes)) 0x 96

the aead secret is redacted.

/proc/sys/core/net/xfrm_redact_secret is a toggle.
Once enabled, either at compile or via proc, it can not be disabled.
Redacting secret is a FIPS 140-2 requirement.

v1->v2
 - add size checks before memset calls
v1->v3
 - replace spaces with tabs for consistancy

Signed-off-by: Antony Antony 
---
 Documentation/networking/xfrm_sysctl.rst |  7 +++
 include/net/netns/xfrm.h |  1 +
 net/xfrm/Kconfig | 10 
 net/xfrm/xfrm_sysctl.c   | 20 +++
 net/xfrm/xfrm_user.c | 76 +---
 5 files changed, 105 insertions(+), 9 deletions(-)

diff --git a/Documentation/networking/xfrm_sysctl.rst 
b/Documentation/networking/xfrm_sysctl.rst
index 47b9bbdd0179..26432b0ff3ac 100644
--- a/Documentation/networking/xfrm_sysctl.rst
+++ b/Documentation/networking/xfrm_sysctl.rst
@@ -9,3 +9,10 @@ XFRM Syscall
 
 xfrm_acq_expires - INTEGER
default 30 - hard timeout in seconds for acquire requests
+
+xfrm_redact_secret - INTEGER
+   A toggle to redact xfrm SA's secret to userspace.
+   When true the kernel, netlink message will redact SA secret
+   to userspace. This is part of FIPS 140-2 requirement.
+   Once the value is set to true, either at compile or at run time,
+   it can not be set to false.
diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index 59f45b1e9dac..0ca9328daad4 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -64,6 +64,7 @@ struct netns_xfrm {
u32 sysctl_aevent_rseqth;
int sysctl_larval_drop;
u32 sysctl_acq_expires;
+   u32 sysctl_redact_secret;
 #ifdef CONFIG_SYSCTL
struct ctl_table_header *sysctl_hdr;
 #endif
diff --git a/net/xfrm/Kconfig b/net/xfrm/Kconfig
index 5b9a5ab48111..270a4e906a15 100644
--- a/net/xfrm/Kconfig
+++ b/net/xfrm/Kconfig
@@ -91,6 +91,16 @@ config XFRM_ESP
select CRYPTO_SEQIV
select CRYPTO_SHA256
 
+config XFRM_REDACT_SECRET
+   bool "Redact xfrm SA secret in netlink message"
+   depends on SYSCTL
+   default n
+   help
+ Enable XFRM SA secret redact in the netlink message.
+ Redacting secret is a FIPS 140-2 requirement.
+ Once enabled at compile, the value can not be set to false on
+ a running system.
+
 config XFRM_IPCOMP
tristate
select XFRM_ALGO
diff --git a/net/xfrm/xfrm_sysctl.c b/net/xfrm/xfrm_sysctl.c
index 0c6c5ef65f9d..bff1f55b198e 100644
--- a/net/xfrm/xfrm_sysctl.c
+++ b/net/xfrm/xfrm_sysctl.c
@@ -4,15 +4,25 @@
 #include 
 #include 
 
+#ifdef CONFIG_SYSCTL
+#ifdef CONFIG_XFRM_REDACT_SECRET
+#define XFRM_REDACT_SECRET  1
+#else
+#define XFRM_REDACT_SECRET  0
+#endif
+#endif
+
 static void __net_init __xfrm_sysctl_init(struct net *net)
 {
net->xfrm.sysctl_aevent_etime = XFRM_AE_ETIME;
net->xfrm.sysctl_aevent_rseqth = XFRM_AE_SEQT_SIZE;
net->xfrm.sysctl_larval_drop = 1;
net->xfrm.sysctl_acq_expires = 30;
+   net->xfrm.sysctl_redact_secret = XFRM_REDACT_SECRET;
 }
 
 #ifdef CONFIG_SYSCTL
+
 static struct ctl_table xfrm_table[] = {
{
.procname   = "xfrm_aevent_etime",
@@ -38,6 +48,15 @@ static struct ctl_table xfrm_table[] = {
.mode   = 0644,
.proc_handler   = proc_dointvec
},
+   {
+   .procname   = "xfrm_redact_secret",
+   .maxlen = sizeof(u32),
+   .mode   = 0644,
+   /* only handle a transition from "0" to "1" */
+   .proc_handler   = proc_dointvec_minmax,
+   .extra1 = SYSCTL_ONE,
+   .extra2 = SYSCTL_ONE,
+   },
{}
 };
 
@@ -54,6 +73,7 @@ int __net_init xfrm_sysctl_init(struct net *net)
table[1].data = &net->xfrm.sysctl_aevent_rseqth;
table[2].data = &net->xfrm.sysctl_larval_drop;
table[3].data = &net->xfrm.sysctl_acq_expires;
+   table[4].data = &net->xfrm.sysctl_redact_secret;
 
/* Don't export sysctls to unprivileged users */
if (net->user_ns != &init_user_ns)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index fbb7d9d06478..c33ebc166e04 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -848,21 +848,78 @@ static int copy_user_offload(struct xfrm_state_offload 
*xso, struct sk_buff *skb
return 0;
 }
 
-static 

[PATCH 3/3] xfrm: clone XFRMA_SEC_CTX during xfrm_do_migrate

2020-08-20 Thread Antony Antony
XFRMA_SEC_CTX was not cloned from the old to the new.
Migrate this attribute during XFRMA_MSG_MIGRATE

Signed-off-by: Antony Antony 
---
 net/xfrm/xfrm_state.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 20a12c67a931..dbcb71b800b8 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1441,6 +1441,30 @@ int xfrm_state_add(struct xfrm_state *x)
 EXPORT_SYMBOL(xfrm_state_add);
 
 #ifdef CONFIG_XFRM_MIGRATE
+static inline bool clone_security(struct xfrm_state *x, struct xfrm_sec_ctx 
*security)
+{
+   struct xfrm_user_sec_ctx *uctx;
+   int size = sizeof(*uctx) + security->ctx_len;
+   int err;
+
+   uctx = kmalloc(size, GFP_KERNEL);
+   if (!uctx)
+   return true;
+
+   uctx->exttype = XFRMA_SEC_CTX;
+   uctx->len = size;
+   uctx->ctx_doi = security->ctx_doi;
+   uctx->ctx_alg = security->ctx_alg;
+   uctx->ctx_len = security->ctx_len;
+   memcpy(uctx + 1, security->ctx_str, security->ctx_len);
+   err = security_xfrm_state_alloc(x, uctx);
+   kfree(uctx);
+   if (err)
+   return true;
+
+   return false;
+}
+
 static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
   struct xfrm_encap_tmpl *encap)
 {
@@ -1497,6 +1521,10 @@ static struct xfrm_state *xfrm_state_clone(struct 
xfrm_state *orig,
goto error;
}
 
+   if (orig->security)
+   if (clone_security(x, orig->security))
+   goto error;
+
if (orig->coaddr) {
x->coaddr = kmemdup(orig->coaddr, sizeof(*x->coaddr),
GFP_KERNEL);
-- 
2.20.1



[PATCH 2/3] xfrm: clone XFRMA_REPLAY_ESN_VAL in xfrm_do_migrate

2020-08-20 Thread Antony Antony
XFRMA_REPLAY_ESN_VAL was not cloned from the old to the new.
Migrate this attribute during XFRMA_MSG_MIGRATE

Signed-off-by: Antony Antony 
---
 include/net/xfrm.h| 16 ++--
 net/xfrm/xfrm_state.c |  2 +-
 2 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 2737d24ec244..9e806c781025 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1773,21 +1773,17 @@ static inline unsigned int 
xfrm_replay_state_esn_len(struct xfrm_replay_state_es
 static inline int xfrm_replay_clone(struct xfrm_state *x,
 struct xfrm_state *orig)
 {
-   x->replay_esn = kzalloc(xfrm_replay_state_esn_len(orig->replay_esn),
+
+   x->replay_esn = kmemdup(orig->replay_esn,
+   xfrm_replay_state_esn_len(orig->replay_esn),
GFP_KERNEL);
if (!x->replay_esn)
return -ENOMEM;
-
-   x->replay_esn->bmp_len = orig->replay_esn->bmp_len;
-   x->replay_esn->replay_window = orig->replay_esn->replay_window;
-
-   x->preplay_esn = kmemdup(x->replay_esn,
-xfrm_replay_state_esn_len(x->replay_esn),
+   x->preplay_esn = kmemdup(orig->preplay_esn,
+xfrm_replay_state_esn_len(orig->preplay_esn),
 GFP_KERNEL);
-   if (!x->preplay_esn) {
-   kfree(x->replay_esn);
+   if (!x->preplay_esn)
return -ENOMEM;
-   }
 
return 0;
 }
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 3a000f289dcd..20a12c67a931 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1522,7 +1522,7 @@ static struct xfrm_state *xfrm_state_clone(struct 
xfrm_state *orig,
x->tfcpad = orig->tfcpad;
x->replay_maxdiff = orig->replay_maxdiff;
x->replay_maxage = orig->replay_maxage;
-   x->curlft.add_time = orig->curlft.add_time;
+   x->curlft = orig->curlft;
x->km.state = orig->km.state;
x->km.seq = orig->km.seq;
x->replay = orig->replay;
-- 
2.20.1



[PATCH 1/3] xfrm: clone XFRMA_SET_MARK during xfrm_do_migrate

2020-08-20 Thread Antony Antony
XFRMA_SET_MARK and XFRMA_SET_MARK_MASK was not cloned from the old
to the new. Migrate these two attributes during XFRMA_MSG_MIGRATE

Signed-off-by: Antony Antony 
---
 net/xfrm/xfrm_state.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 69520ad3d83b..3a000f289dcd 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1510,6 +1510,7 @@ static struct xfrm_state *xfrm_state_clone(struct 
xfrm_state *orig,
}
 
memcpy(&x->mark, &orig->mark, sizeof(x->mark));
+   memcpy(&x->props.smark, &orig->props.smark, sizeof(x->props.smark));
 
if (xfrm_init_state(x) < 0)
goto error;
-- 
2.20.1



[PATCH ipsec-next v2] xfrm: add /proc/sys/core/net/xfrm_redact_secret

2020-08-20 Thread Antony Antony
when enabled, 1, redact XFRM SA secret in the netlink response to
xfrm_get_sa() or dump all sa.

e.g
echo 1 > /proc/sys/net/core/xfrm_redact_secret
ip xfrm state
src 172.16.1.200 dst 172.16.1.100
proto esp spi 0x0002 reqid 2 mode tunnel
replay-window 0
aead rfc4106(gcm(aes)) 0x 96

the aead secret is redacted.

/proc/sys/core/net/xfrm_redact_secret is a toggle.
Once enabled, either at compile or via proc, it can not be disabled.
Redacting secret is a FIPS 140-2 requirement.

---

Signed-off-by: Antony Antony 
---
v1->v2
 - add size checks before memset calls

 Documentation/networking/xfrm_sysctl.rst |  7 +++
 include/net/netns/xfrm.h |  1 +
 net/xfrm/Kconfig | 10 
 net/xfrm/xfrm_sysctl.c   | 20 +++
 net/xfrm/xfrm_user.c | 76 +---
 5 files changed, 105 insertions(+), 9 deletions(-)

diff --git a/Documentation/networking/xfrm_sysctl.rst 
b/Documentation/networking/xfrm_sysctl.rst
index 47b9bbdd0179..26432b0ff3ac 100644
--- a/Documentation/networking/xfrm_sysctl.rst
+++ b/Documentation/networking/xfrm_sysctl.rst
@@ -9,3 +9,10 @@ XFRM Syscall
 
 xfrm_acq_expires - INTEGER
default 30 - hard timeout in seconds for acquire requests
+
+xfrm_redact_secret - INTEGER
+   A toggle to redact xfrm SA's secret to userspace.
+   When true the kernel, netlink message will redact SA secret
+   to userspace. This is part of FIPS 140-2 requirement.
+   Once the value is set to true, either at compile or at run time,
+   it can not be set to false.
diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index 59f45b1e9dac..0ca9328daad4 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -64,6 +64,7 @@ struct netns_xfrm {
u32 sysctl_aevent_rseqth;
int sysctl_larval_drop;
u32 sysctl_acq_expires;
+   u32 sysctl_redact_secret;
 #ifdef CONFIG_SYSCTL
struct ctl_table_header *sysctl_hdr;
 #endif
diff --git a/net/xfrm/Kconfig b/net/xfrm/Kconfig
index 5b9a5ab48111..270a4e906a15 100644
--- a/net/xfrm/Kconfig
+++ b/net/xfrm/Kconfig
@@ -91,6 +91,16 @@ config XFRM_ESP
select CRYPTO_SEQIV
select CRYPTO_SHA256
 
+config XFRM_REDACT_SECRET
+   bool "Redact xfrm SA secret in netlink message"
+   depends on SYSCTL
+   default n
+   help
+ Enable XFRM SA secret redact in the netlink message.
+ Redacting secret is a FIPS 140-2 requirement.
+ Once enabled at compile, the value can not be set to false on
+ a running system.
+
 config XFRM_IPCOMP
tristate
select XFRM_ALGO
diff --git a/net/xfrm/xfrm_sysctl.c b/net/xfrm/xfrm_sysctl.c
index 0c6c5ef65f9d..a41aa325a478 100644
--- a/net/xfrm/xfrm_sysctl.c
+++ b/net/xfrm/xfrm_sysctl.c
@@ -4,15 +4,25 @@
 #include 
 #include 
 
+#ifdef CONFIG_SYSCTL
+#ifdef CONFIG_XFRM_REDACT_SECRET
+#define XFRM_REDACT_SECRET  1
+#else
+#define XFRM_REDACT_SECRET  0
+#endif
+#endif
+
 static void __net_init __xfrm_sysctl_init(struct net *net)
 {
net->xfrm.sysctl_aevent_etime = XFRM_AE_ETIME;
net->xfrm.sysctl_aevent_rseqth = XFRM_AE_SEQT_SIZE;
net->xfrm.sysctl_larval_drop = 1;
net->xfrm.sysctl_acq_expires = 30;
+   net->xfrm.sysctl_redact_secret = XFRM_REDACT_SECRET;
 }
 
 #ifdef CONFIG_SYSCTL
+
 static struct ctl_table xfrm_table[] = {
{
.procname   = "xfrm_aevent_etime",
@@ -38,6 +48,15 @@ static struct ctl_table xfrm_table[] = {
.mode   = 0644,
.proc_handler   = proc_dointvec
},
+   {
+   .procname   = "xfrm_redact_secret",
+   .maxlen = sizeof(u32),
+   .mode   = 0644,
+   /* only handle a transition from "0" to "1" */
+   .proc_handler   = proc_dointvec_minmax,
+   .extra1 = SYSCTL_ONE,
+   .extra2 = SYSCTL_ONE,
+   },
{}
 };
 
@@ -54,6 +73,7 @@ int __net_init xfrm_sysctl_init(struct net *net)
table[1].data = &net->xfrm.sysctl_aevent_rseqth;
table[2].data = &net->xfrm.sysctl_larval_drop;
table[3].data = &net->xfrm.sysctl_acq_expires;
+   table[4].data = &net->xfrm.sysctl_redact_secret;
 
/* Don't export sysctls to unprivileged users */
if (net->user_ns != &init_user_ns)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index fbb7d9d06478..c33ebc166e04 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -848,21 +848,78 @@ static int copy_user_offload(struct xfrm_state_offload 
*xso, struct sk_buff *skb
return 0;
 }
 
-static int copy_to_user_auth(struct xfr

Re: [PATCH ipsec-next] xfrm: add /proc/sys/core/net/xfrm_redact_secret

2020-08-20 Thread Antony Antony
On Tue, Jul 28, 2020 at 21:09:10 +0200, Stephan Mueller wrote:
> Am Dienstag, 28. Juli 2020, 17:47:30 CEST schrieb Antony Antony:
> 
> Hi Antony,
> 
> > when enabled, 1, redact XFRM SA secret in the netlink response to
> > xfrm_get_sa() or dump all sa.
> > 
> > e.g
> > echo 1 > /proc/sys/net/core/xfrm_redact_secret
> > ip xfrm state
> > src 172.16.1.200 dst 172.16.1.100
> > proto esp spi 0x0002 reqid 2 mode tunnel
> > replay-window 0
> > aead rfc4106(gcm(aes)) 0x 96
> > 
> > the aead secret is redacted.
> > 
> > /proc/sys/core/net/xfrm_redact_secret is a toggle.
> > Once enabled, either at compile or via proc, it can not be disabled.
> > Redacting secret is a FIPS 140-2 requirement.
> > 
> > Cc: Stephan Mueller 
> > Signed-off-by: Antony Antony 
> > ---
> >  Documentation/networking/xfrm_sysctl.rst |  7 +++
> >  include/net/netns/xfrm.h |  1 +
> >  net/xfrm/Kconfig | 10 
> >  net/xfrm/xfrm_sysctl.c   | 20 +++
> >  net/xfrm/xfrm_user.c | 76 +---
> >  5 files changed, 105 insertions(+), 9 deletions(-)
> > 
> > diff --git a/Documentation/networking/xfrm_sysctl.rst
> > b/Documentation/networking/xfrm_sysctl.rst index 47b9bbdd0179..26432b0ff3ac
> > 100644
> > --- a/Documentation/networking/xfrm_sysctl.rst
> > +++ b/Documentation/networking/xfrm_sysctl.rst
> > @@ -9,3 +9,10 @@ XFRM Syscall
> > 
> >  xfrm_acq_expires - INTEGER
> > default 30 - hard timeout in seconds for acquire requests
> > +
> > +xfrm_redact_secret - INTEGER
> > +   A toggle to redact xfrm SA's secret to userspace.
> > +   When true the kernel, netlink message will redact SA secret
> > +   to userspace. This is part of FIPS 140-2 requirement.
> > +   Once the value is set to true, either at compile or at run time,
> > +   it can not be set to false.
> > diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
> > index 59f45b1e9dac..0ca9328daad4 100644
> > --- a/include/net/netns/xfrm.h
> > +++ b/include/net/netns/xfrm.h
> > @@ -64,6 +64,7 @@ struct netns_xfrm {
> > u32 sysctl_aevent_rseqth;
> > int sysctl_larval_drop;
> > u32 sysctl_acq_expires;
> > +   u32 sysctl_redact_secret;
> >  #ifdef CONFIG_SYSCTL
> > struct ctl_table_header *sysctl_hdr;
> >  #endif
> > diff --git a/net/xfrm/Kconfig b/net/xfrm/Kconfig
> > index 5b9a5ab48111..270a4e906a15 100644
> > --- a/net/xfrm/Kconfig
> > +++ b/net/xfrm/Kconfig
> > @@ -91,6 +91,16 @@ config XFRM_ESP
> > select CRYPTO_SEQIV
> > select CRYPTO_SHA256
> > 
> > +config XFRM_REDACT_SECRET
> > +   bool "Redact xfrm SA secret in netlink message"
> > +   depends on SYSCTL
> > +   default n
> > +   help
> > + Enable XFRM SA secret redact in the netlink message.
> > + Redacting secret is a FIPS 140-2 requirement.
> > + Once enabled at compile, the value can not be set to false on
> > + a running system.
> > +
> >  config XFRM_IPCOMP
> > tristate
> > select XFRM_ALGO
> > diff --git a/net/xfrm/xfrm_sysctl.c b/net/xfrm/xfrm_sysctl.c
> > index 0c6c5ef65f9d..a41aa325a478 100644
> > --- a/net/xfrm/xfrm_sysctl.c
> > +++ b/net/xfrm/xfrm_sysctl.c
> > @@ -4,15 +4,25 @@
> >  #include 
> >  #include 
> > 
> > +#ifdef CONFIG_SYSCTL
> > +#ifdef CONFIG_XFRM_REDACT_SECRET
> > +#define XFRM_REDACT_SECRET  1
> > +#else
> > +#define XFRM_REDACT_SECRET  0
> > +#endif
> > +#endif
> > +
> >  static void __net_init __xfrm_sysctl_init(struct net *net)
> >  {
> > net->xfrm.sysctl_aevent_etime = XFRM_AE_ETIME;
> > net->xfrm.sysctl_aevent_rseqth = XFRM_AE_SEQT_SIZE;
> > net->xfrm.sysctl_larval_drop = 1;
> > net->xfrm.sysctl_acq_expires = 30;
> > +   net->xfrm.sysctl_redact_secret = XFRM_REDACT_SECRET;
> >  }
> > 
> >  #ifdef CONFIG_SYSCTL
> > +
> >  static struct ctl_table xfrm_table[] = {
> > {
> > .procname   = "xfrm_aevent_etime",
> > @@ -38,6 +48,15 @@ static struct ctl_table xfrm_table[] = {
> > .mode   = 0644,
> > .proc_handler   = proc_dointvec
> > },
> > +   {
> > +   .procname   = "xfrm_redact_secret",
> > +  

Re: [PATCH ipsec-next] xfrm: add /proc/sys/core/net/xfrm_redact_secret

2020-07-28 Thread Antony Antony
On Wed, Jul 29, 2020 at 02:22:52 +1000, Herbert Xu wrote:
> On Tue, Jul 28, 2020 at 05:47:30PM +0200, Antony Antony wrote:
> > when enabled, 1, redact XFRM SA secret in the netlink response to
> > xfrm_get_sa() or dump all sa.
> > 
> > e.g
> > echo 1 > /proc/sys/net/core/xfrm_redact_secret
> > ip xfrm state
> > src 172.16.1.200 dst 172.16.1.100
> > proto esp spi 0x0002 reqid 2 mode tunnel
> > replay-window 0
> > aead rfc4106(gcm(aes)) 0x 96
> > 
> > the aead secret is redacted.
> > 
> > /proc/sys/core/net/xfrm_redact_secret is a toggle.
> > Once enabled, either at compile or via proc, it can not be disabled.
> > Redacting secret is a FIPS 140-2 requirement.
> 
> Couldn't you use the existing fips_enabled sysctl?

that could be a step, however, not yet.

Libreswan in FIPS mode with xfrm_redact_secret enabled would work fine, 
however, enabling xfrm_redact_secret would break Strongswan in FIPS mode. We 
can add this option fips_enabled once Strongswan does not need SA secret, 
child_sa->update().

Also there was interest to able to use xfrm_redact_secret independent of FIPS.

I thik for now it best to be ouside fips_enabled.



[PATCH ipsec-next] xfrm: add /proc/sys/core/net/xfrm_redact_secret

2020-07-28 Thread Antony Antony
when enabled, 1, redact XFRM SA secret in the netlink response to
xfrm_get_sa() or dump all sa.

e.g
echo 1 > /proc/sys/net/core/xfrm_redact_secret
ip xfrm state
src 172.16.1.200 dst 172.16.1.100
proto esp spi 0x0002 reqid 2 mode tunnel
replay-window 0
aead rfc4106(gcm(aes)) 0x 96

the aead secret is redacted.

/proc/sys/core/net/xfrm_redact_secret is a toggle.
Once enabled, either at compile or via proc, it can not be disabled.
Redacting secret is a FIPS 140-2 requirement.

Cc: Stephan Mueller 
Signed-off-by: Antony Antony 
---
 Documentation/networking/xfrm_sysctl.rst |  7 +++
 include/net/netns/xfrm.h |  1 +
 net/xfrm/Kconfig | 10 
 net/xfrm/xfrm_sysctl.c   | 20 +++
 net/xfrm/xfrm_user.c | 76 +---
 5 files changed, 105 insertions(+), 9 deletions(-)

diff --git a/Documentation/networking/xfrm_sysctl.rst 
b/Documentation/networking/xfrm_sysctl.rst
index 47b9bbdd0179..26432b0ff3ac 100644
--- a/Documentation/networking/xfrm_sysctl.rst
+++ b/Documentation/networking/xfrm_sysctl.rst
@@ -9,3 +9,10 @@ XFRM Syscall
 
 xfrm_acq_expires - INTEGER
default 30 - hard timeout in seconds for acquire requests
+
+xfrm_redact_secret - INTEGER
+   A toggle to redact xfrm SA's secret to userspace.
+   When true the kernel, netlink message will redact SA secret
+   to userspace. This is part of FIPS 140-2 requirement.
+   Once the value is set to true, either at compile or at run time,
+   it can not be set to false.
diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index 59f45b1e9dac..0ca9328daad4 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -64,6 +64,7 @@ struct netns_xfrm {
u32 sysctl_aevent_rseqth;
int sysctl_larval_drop;
u32 sysctl_acq_expires;
+   u32 sysctl_redact_secret;
 #ifdef CONFIG_SYSCTL
struct ctl_table_header *sysctl_hdr;
 #endif
diff --git a/net/xfrm/Kconfig b/net/xfrm/Kconfig
index 5b9a5ab48111..270a4e906a15 100644
--- a/net/xfrm/Kconfig
+++ b/net/xfrm/Kconfig
@@ -91,6 +91,16 @@ config XFRM_ESP
select CRYPTO_SEQIV
select CRYPTO_SHA256
 
+config XFRM_REDACT_SECRET
+   bool "Redact xfrm SA secret in netlink message"
+   depends on SYSCTL
+   default n
+   help
+ Enable XFRM SA secret redact in the netlink message.
+ Redacting secret is a FIPS 140-2 requirement.
+ Once enabled at compile, the value can not be set to false on
+ a running system.
+
 config XFRM_IPCOMP
tristate
select XFRM_ALGO
diff --git a/net/xfrm/xfrm_sysctl.c b/net/xfrm/xfrm_sysctl.c
index 0c6c5ef65f9d..a41aa325a478 100644
--- a/net/xfrm/xfrm_sysctl.c
+++ b/net/xfrm/xfrm_sysctl.c
@@ -4,15 +4,25 @@
 #include 
 #include 
 
+#ifdef CONFIG_SYSCTL
+#ifdef CONFIG_XFRM_REDACT_SECRET
+#define XFRM_REDACT_SECRET  1
+#else
+#define XFRM_REDACT_SECRET  0
+#endif
+#endif
+
 static void __net_init __xfrm_sysctl_init(struct net *net)
 {
net->xfrm.sysctl_aevent_etime = XFRM_AE_ETIME;
net->xfrm.sysctl_aevent_rseqth = XFRM_AE_SEQT_SIZE;
net->xfrm.sysctl_larval_drop = 1;
net->xfrm.sysctl_acq_expires = 30;
+   net->xfrm.sysctl_redact_secret = XFRM_REDACT_SECRET;
 }
 
 #ifdef CONFIG_SYSCTL
+
 static struct ctl_table xfrm_table[] = {
{
.procname   = "xfrm_aevent_etime",
@@ -38,6 +48,15 @@ static struct ctl_table xfrm_table[] = {
.mode   = 0644,
.proc_handler   = proc_dointvec
},
+   {
+   .procname   = "xfrm_redact_secret",
+   .maxlen = sizeof(u32),
+   .mode   = 0644,
+   /* only handle a transition from "0" to "1" */
+   .proc_handler   = proc_dointvec_minmax,
+   .extra1 = SYSCTL_ONE,
+   .extra2 = SYSCTL_ONE,
+   },
{}
 };
 
@@ -54,6 +73,7 @@ int __net_init xfrm_sysctl_init(struct net *net)
table[1].data = &net->xfrm.sysctl_aevent_rseqth;
table[2].data = &net->xfrm.sysctl_larval_drop;
table[3].data = &net->xfrm.sysctl_acq_expires;
+   table[4].data = &net->xfrm.sysctl_redact_secret;
 
/* Don't export sysctls to unprivileged users */
if (net->user_ns != &init_user_ns)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index e6cfaa680ef3..a3e89dddea9d 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -848,21 +848,78 @@ static int copy_user_offload(struct xfrm_state_offload 
*xso, struct sk_buff *skb
return 0;
 }
 
-static int copy_to_user_auth(struct xfrm_algo_auth *auth, struct sk_buff *skb)
+static int c

[PATCH] ip: xfrm if_id -ve value is error

2019-04-09 Thread Antony Antony
if_id is u32, error on -ve values instead of setting to 0
after :
ip link add ipsec0 type xfrm dev enp0s5 if_id -10
Error: argument "-10" is wrong: if_id value is invalid

before :
ip link add ipsec0 type xfrm dev enp0s5 if_id -10
ip -d  link show dev ipsec0
67: ipsec0@enp0s5:  mtu 1500 qdisc noop state DOWN mode DEFAULT group 
default qlen 1000
link/none 00:1c:42:55:d6:ab brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 
maxmtu 1500
xfrm if_id 0 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 
65536 gso_max_segs 65535

Fixes: 286446c1e8c error on -ve if_id

Signed-off-by: Antony Antony 
---
 ip/link_xfrm.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/ip/link_xfrm.c b/ip/link_xfrm.c
index 79a902fd..7f66bad6 100644
--- a/ip/link_xfrm.c
+++ b/ip/link_xfrm.c
@@ -34,7 +34,9 @@ static int xfrm_parse_opt(struct link_util *lu, int argc, 
char **argv,
exit(nodev(*argv));
} else if (!matches(*argv, "if_id")) {
NEXT_ARG();
-   if (!get_u32(&if_id, *argv, 0))
+   if (get_u32(&if_id, *argv, 0))
+   invarg("if_id value is invalid", *argv);
+   else
addattr32(n, 1024, IFLA_XFRM_IF_ID, if_id);
} else {
xfrm_print_help(lu, argc, argv, stderr);
-- 
2.17.2



Re: [PATCH iproute2-next] ip xfrm: support setting/printing XFRMA_IF_ID attribute in states/policies

2019-04-05 Thread Antony Antony
On Fri, Apr 05, 2019 at 03:07:58PM -0700, Stephen Hemminger wrote:
> On Thu,  4 Apr 2019 19:07:38 +0300
> Eyal Birger  wrote:
> 
> > The XFRMA_IF_ID attribute is set in policies/states for them to be
> > associated with an XFRM interface (4.19+).
> > 
> > Add support for setting / displaying this attribute.
> > 
> > Note that 0 is a valid value therefore set XFRMA_IF_ID if any value
> > was provided in command line.
> > 
> > Tested-by: Antony Antony 
> > Signed-off-by: Eyal Birger 
> 
> This is already handled by an earlier patch, that I just applied

Do you  mean commit 286446c1
https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/commit/?id=286446c1e8c7f5f6eca4959015aa9e482b7adb11

Matt's patch is to support link.  
e.g ip link add ipsec0 type xfrm dev enp0s5 if_id 0xAB

Eyal's patch for xfrm state and policy.
e.g 
ip xfrm policy add src 10.1.1.200/32 dst 10.1.1.100/32 dir in tmpl src 
172.16.1.200 dst 172.16.1.100 proto esp reqid 2 mode tunnel if_id 10

Thanks for applying Matt's patch. We need for both patches.

-antony


Re: [iproute2] ip: support for xfrm interfaces

2019-04-05 Thread Antony Antony


Tested-by: Antony Antony 

On Fri, Apr 05, 2019 at 03:46:02PM -0400, Matt Ellison wrote:
> I recently submitted v3 of the patch, please take a look there.

great. I am testing v3 now.

One comment. It seems to accept -ve value for if_id and quietly set to 0
may be throw an error for -ve values? or take it as u32?
in my opinion setting to 0 is confusing

sudo ./ip/ip link add ipsec0 type xfrm dev enp0s5 if_id -10
build@d28:~/git/iproute2 (master)$ ./ip/ip -d link show ipsec0
33: ipsec0@enp0s5:  mtu 1500 qdisc noop state DOWN mode DEFAULT group 
default qlen 1000
link/none 00:1c:42:55:d6:ab brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 
maxmtu 1500
xfrm if_id 0 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 
65536 gso_max_segs 65535

> > Question: is it easy to add "if_id" to "ip link show" output?
> 
> Yes, it should show up under the detailed output for the interface (-d).

great thanks.

sudo ./ip/ip link add ipsec0 type xfrm dev enp0s5 if_id 0xAB

./ip/ip -d link show ipsec0
29: ipsec0@enp0s5:  mtu 1500 qdisc noop state DOWN mode DEFAULT group 
default qlen 1000
link/none 00:1c:42:55:d6:ab brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 
maxmtu 1500
xfrm if_id 0xab addrgenmode eui64 numtxqueues 1 numrxqueues 1 
gso_max_size 65536 gso_max_segs 65535

thanks,
-antony


Re: [iproute2] ip: support for xfrm interfaces

2019-04-04 Thread Antony Antony
Tested-by: Antony Antony 

Question: is it easy to add "if_id" to "ip link show" output?
currently:
ip link show ipsec0
4: ipsec0@eth1:  mtu 1500 qdisc noqueue state UNKNOWN mode 
DEFAULT group default qlen 1000
link/none da:25:61:2e:0c:98 brd ff:ff:ff:ff:ff:ff

proposed:
4: ipsec0@eth1:  mtu 1500 qdisc noqueue xfrm_if_id 0x1 
state UNKNOWN mode DEFAULT group default qlen 1000
link/none da:25:61:2e:0c:98 brd ff:ff:ff:ff:ff:ff

thanks,
-antony

On Tue, Jan 01, 2019 at 12:40:01PM -0500, Matt Ellison wrote:
> Support for new (4.19+) xfrm virtual interfaces.
> 
> Interfaces take a 'if_id' which is an interface id which can be set on
> an xfrm policy as its interface lookup key (XFRMA_IF_ID).
> 
> Signed-off-by: Matt Ellison 
> ---
>  ip/Makefile |  2 +-
>  ip/iplink.c |  3 +-
>  ip/link_xfrm.c  | 79 +
>  man/man8/ip-link.8.in   | 27 -
>  testsuite/tests/ip/link/add_type_xfrm.t | 32 ++
>  5 files changed, 140 insertions(+), 3 deletions(-)
>  create mode 100644 ip/link_xfrm.c
>  create mode 100755 testsuite/tests/ip/link/add_type_xfrm.t
> 
> diff --git a/ip/Makefile b/ip/Makefile
> index a88f9366..7ce6e91a 100644
> --- a/ip/Makefile
> +++ b/ip/Makefile
> @@ -5,7 +5,7 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o 
> ipnetns.o \
>  ipxfrm.o xfrm_state.o xfrm_policy.o xfrm_monitor.o iplink_dummy.o \
>  iplink_ifb.o iplink_nlmon.o iplink_team.o iplink_vcan.o iplink_vxcan.o \
>  iplink_vlan.o link_veth.o link_gre.o iplink_can.o iplink_xdp.o \
> -iplink_macvlan.o ipl2tp.o link_vti.o link_vti6.o \
> +iplink_macvlan.o ipl2tp.o link_vti.o link_vti6.o link_xfrm.o \
>  iplink_vxlan.o tcp_metrics.o iplink_ipoib.o ipnetconf.o link_ip6tnl.o \
>  link_iptnl.o link_gre6.o iplink_bond.o iplink_bond_slave.o iplink_hsr.o \
>  iplink_bridge.o iplink_bridge_slave.o ipfou.o iplink_ipvlan.o \
> diff --git a/ip/iplink.c b/ip/iplink.c
> index b5519201..f61e570a 100644
> --- a/ip/iplink.c
> +++ b/ip/iplink.c
> @@ -121,7 +121,8 @@ void iplink_usage(void)
>   "  bridge | bond | team | ipoib | ip6tnl | ipip 
> | sit | vxlan |\n"
>   "  gre | gretap | erspan | ip6gre | ip6gretap | 
> ip6erspan |\n"
>   "  vti | nlmon | team_slave | bond_slave | 
> bridge_slave |\n"
> - "  ipvlan | ipvtap | geneve | vrf | macsec | 
> netdevsim | rmnet }\n");
> + "  ipvlan | ipvtap | geneve | vrf | macsec | 
> netdevsim | rmnet |\n"
> + "  xfrm }\n");
>   }
>   exit(-1);
>  }
> diff --git a/ip/link_xfrm.c b/ip/link_xfrm.c
> new file mode 100644
> index ..1115fde5
> --- /dev/null
> +++ b/ip/link_xfrm.c
> @@ -0,0 +1,79 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * link_xfrm.c   Virtual XFRM Interface driver module
> + *
> + * Authors:  Matt Ellison 
> + */
> +
> +#include 
> +#include 
> +
> +#include "rt_names.h"
> +#include "utils.h"
> +#include "ip_common.h"
> +#include "tunnel.h"
> +
> +static void xfrm_print_help(struct link_util *lu, int argc, char **argv,
> + FILE *f)
> +{
> + fprintf(f, "Usage: ... %-4s dev PHYS_DEV [ if_id IF-ID ]\n", lu->id);
> + fprintf(f, "\nWhere: IF-ID := { 0x0..0x }\n");
> +}
> +
> +static int xfrm_parse_opt(struct link_util *lu, int argc, char **argv,
> +   struct nlmsghdr *n)
> +{
> + unsigned int link = 0;
> + __u32 if_id = 0;
> +
> + while (argc > 0) {
> + if (!matches(*argv, "dev")) {
> + NEXT_ARG();
> + link = ll_name_to_index(*argv);
> + if (!link)
> + exit(nodev(*argv));
> + } else if (!matches(*argv, "if_id")) {
> + NEXT_ARG();
> + if (get_u32(&if_id, *argv, 0))
> + invarg("if_id", *argv);
> + } else {
> + xfrm_print_help(lu, argc, argv, stderr);
> + return -1;
> + }
> + argc--; argv++;
> + }
> +
> + addattr32(n, 1024, IFLA_XFRM_IF_ID, if_id);
> +
> + if (link) {
> + addattr32(n, 1024, IFLA_XFRM_LINK, link);
> + } else {
> + fprintf(stderr, "must specify physical

Re: [ipsec-next,0/7] : Support multiple VTIs with the same src+dst pair

2018-01-05 Thread Antony Antony
Hi Lorenzo,
I agree vti is very limiting! I am glad to hear about xfrmi.

I saw two tunnels between gateways send traffic using VTI. So I am curious 
what is different in your case. Or are you dealing with something else?

Here are a couple of outputs from libreswan testing 

this is the verbose output.
https://swantest.libreswan.fi/results/blackswan/2018-01-05-swantest-3.22-596-g6bac0de35-master/netkey-vti-09/OUTPUT/west.console.verbose.txt

[root@west netkey-vti-09]# ip xfrm state
src 192.1.2.23 dst 192.1.2.45
proto esp spi 0x0eb97a56 reqid 16393 mode tunnel
replay-window 32 flag af-unspec
aead rfc4106(gcm(aes)) 
0xcf25becdc6c196ff04b9e893d2caa387ed63bc96cf66ab7c1e5c74d32b9eeb801f06fbf3 
128
src 192.1.2.45 dst 192.1.2.23
proto esp spi 0x507929e8 reqid 16393 mode tunnel
replay-window 32 flag af-unspec
aead rfc4106(gcm(aes)) 
0x8b5f8143cb6f361e57b0096bc1a444a65e244f97ba76e8779b968bcae54b78cea7c17d38 
128
src 192.1.2.23 dst 192.1.2.45
proto esp spi 0x73eab5cf reqid 16389 mode tunnel
replay-window 32 flag af-unspec
aead rfc4106(gcm(aes)) 
0xb00cc4d0da414cba35c9a41e176fdafb92af0a7912d633c1c3f4623bee2d090173e3fca3 
128
src 192.1.2.45 dst 192.1.2.23
proto esp spi 0x52581beb reqid 16389 mode tunnel
replay-window 32 flag af-unspec
aead rfc4106(gcm(aes)) 
0x01b906499806ec2436ffe125f54ce297c3a3a14bb19fcbf51f16888c6927a20cd0dc5e67 
128

a santized output 
https://swantest.libreswan.fi/results/blackswan/2018-01-05-swantest-3.22-596-g6bac0de35-master/netkey-vti-09/OUTPUT/west.console.txt

Also from an older test:
https://swantest.libreswan.fi/results/blackswan/2018-01-04-swantest-3.22-596-g6bac0de35-master/netkey-vti-02/OUTPUT/west.console.txt

regards,
-antony

On Thu, Dec 21, 2017 at 02:06:00AM +0900, Lorenzo Colitti wrote:
> When using IPsec tunnel mode, VTIs provide many benefits compared
> to direct configuration of xfrm policies / states. However, one
> limitation is that there can only be one VTI between a given pair
> of IP addresses. This does not allow configuring multiple IPsec
> tunnels to the same security gateway. This is required by some
> deployments, for example I-WLAN [3GPP TS 24.327].
> 
> This patchset introduces a new VTI_KEYED flag that allows
> configuration of multiple VTIs between the same IP address
> pairs. The semantics are as follows:
> 
> - The output path is the same as current VTI behaviour, where a
>   routing lookup selects a VTI interface, and the VTI's okey
>   specifies the mark to use in the XFRM lookup.
> - The input and ICMP error paths instead work by first looking up
>   an SA with a loose match that ignores the mark. That mark is
>   then used to find the tunnel by ikey (for input packets) or
>   okey (for ICMP errors).
> 
> In order for ICMP errors to work, flags are added to the common
> IP lookup functions to ignore the tunnel ikey and to look up
> tunnels by okey instead of ikey.
> 
> On the same IP address pair, keyed VTIs can coexist with each
> other (as long as the ikeys are different), but cannot coexist
> with keyless VTIs. This is because the existing keyless VTI
> behaviour (which this series does not change) is to always accept
> packets matching an input policy, regardless of whether there is
> any matching XFRM state. Thus, the keyless VTI would accept the
> traffic for the keyed tunnel and drop it because it would not
> match the keyed tunnel's state.
> 
> Changes from RFC series:
> - Processing of ICMP errors now works when ikey != okey.
> - Series now contains changes to the common tunnel lookup
>   functions to match tunnels by okey and to ignore ikey when
>   matching.
> - Fixed missing EXPORT_SYMBOL for xfrm_state_lookup_loose.
> - Made vti6_lookup static as it should have been.


[PATCH] xfrm: fix xfrm_do_migrate() with AEAD e.g(AES-GCM)

2017-12-07 Thread Antony Antony
copy geniv when cloning the xfrm state.

x->geniv was not copied to the new state and migration would fail.

xfrm_do_migrate
  ..
  xfrm_state_clone()
   ..
   ..
   esp_init_aead()
   crypto_alloc_aead()
crypto_alloc_tfm()
 crypto_find_alg() return EAGAIN and failed

Signed-off-by: Antony Antony 
---
 net/xfrm/xfrm_state.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 065d89606888..500b3391f474 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1343,6 +1343,7 @@ static struct xfrm_state *xfrm_state_clone(struct 
xfrm_state *orig,
 
if (orig->aead) {
x->aead = xfrm_algo_aead_clone(orig->aead);
+   x->geniv = orig->geniv;
if (!x->aead)
goto error;
}
-- 
2.13.6



[PATCH v2 1/2] xfrm: extend MIGRATE with UDP encapsulation port

2017-06-06 Thread Antony Antony
Add UDP encapsulation port to XFRM_MSG_MIGRATE using an optional
netlink attribute XFRMA_ENCAP.

The devices that support IKE MOBIKE extension (RFC-4555 Section 3.8)
could go to sleep for a few minutes and wake up. When it wake up the
NAT mapping could have expired, the device send a MOBIKE UPDATE_SA
message to migrate the IPsec SA. The change could be a change UDP
encapsulation port, IP address, or both.

Reported-by: Paul Wouters 
Signed-off-by: Antony Antony 
Reviewed-by: Richard Guy Briggs 
---
 include/net/xfrm.h |  6 --
 net/key/af_key.c   |  2 +-
 net/xfrm/xfrm_policy.c | 11 ---
 net/xfrm/xfrm_state.c  | 18 +-
 net/xfrm/xfrm_user.c   | 14 --
 5 files changed, 34 insertions(+), 17 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 7e7e2b0..df98463 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1678,10 +1678,12 @@ int km_migrate(const struct xfrm_selector *sel, u8 dir, 
u8 type,
   const struct xfrm_kmaddress *k);
 struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net 
*net);
 struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
- struct xfrm_migrate *m);
+ struct xfrm_migrate *m,
+ struct xfrm_encap_tmpl *encap);
 int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
 struct xfrm_migrate *m, int num_bundles,
-struct xfrm_kmaddress *k, struct net *net);
+struct xfrm_kmaddress *k, struct net *net,
+struct xfrm_encap_tmpl *encap);
 #endif
 
 int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 512dc43..56df9fb 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -2602,7 +2602,7 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff 
*skb,
}
 
return xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i,
-   kma ? &k : NULL, net);
+   kma ? &k : NULL, net, NULL);
 
  out:
return err;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index ed4e52d..eaecfa4 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -3268,11 +3268,6 @@ static int xfrm_migrate_check(const struct xfrm_migrate 
*m, int num_migrate)
return -EINVAL;
 
for (i = 0; i < num_migrate; i++) {
-   if (xfrm_addr_equal(&m[i].old_daddr, &m[i].new_daddr,
-   m[i].old_family) &&
-   xfrm_addr_equal(&m[i].old_saddr, &m[i].new_saddr,
-   m[i].old_family))
-   return -EINVAL;
if (xfrm_addr_any(&m[i].new_daddr, m[i].new_family) ||
xfrm_addr_any(&m[i].new_saddr, m[i].new_family))
return -EINVAL;
@@ -3296,7 +3291,8 @@ static int xfrm_migrate_check(const struct xfrm_migrate 
*m, int num_migrate)
 
 int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
 struct xfrm_migrate *m, int num_migrate,
-struct xfrm_kmaddress *k, struct net *net)
+struct xfrm_kmaddress *k, struct net *net,
+struct xfrm_encap_tmpl *encap)
 {
int i, err, nx_cur = 0, nx_new = 0;
struct xfrm_policy *pol = NULL;
@@ -3319,7 +3315,8 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, 
u8 type,
if ((x = xfrm_migrate_state_find(mp, net))) {
x_cur[nx_cur] = x;
nx_cur++;
-   if ((xc = xfrm_state_migrate(x, mp))) {
+   xc = xfrm_state_migrate(x, mp, encap);
+   if (xc) {
x_new[nx_new] = xc;
nx_new++;
} else {
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 2e291bc..ae6206b 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1309,7 +1309,8 @@ int xfrm_state_add(struct xfrm_state *x)
 EXPORT_SYMBOL(xfrm_state_add);
 
 #ifdef CONFIG_XFRM_MIGRATE
-static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig)
+static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
+  struct xfrm_encap_tmpl *encap)
 {
struct net *net = xs_net(orig);
struct xfrm_state *x = xfrm_state_alloc(net);
@@ -1351,8 +1352,14 @@ static struct xfrm_state *xfrm_state_clone(struct 
xfrm_state *orig)
}
x->props.calgo = orig->props.calgo;
 
-   if (orig->encap) {
-   x->encap = kmemdup(orig->encap, sizeof(*x->encap), GFP_KERNEL);
+   if (encap || orig->encap) {
+   if (encap

[PATCH v2 2/2] xfrm: add UDP encapsulation port in migrate message

2017-06-06 Thread Antony Antony
Add XFRMA_ENCAP, UDP encapsulation port, to km_migrate announcement
to userland. Only add if XFRMA_ENCAP was in user migrate request.

Signed-off-by: Antony Antony 
Reviewed-by: Richard Guy Briggs 
---
Changes in v2:
- fixed pfkey_send_migrate, warning reported by kbuild test robot
  with # CONFIG_NET_KEY_MIGRATE is not set
  also tested with # CONFIG_XFRM_MIGRATE is not set
- constify struct xfrm_encap_tmpl *encap in km_migrate

 include/net/xfrm.h |  6 --
 net/key/af_key.c   |  6 --
 net/xfrm/xfrm_policy.c |  2 +-
 net/xfrm/xfrm_state.c  |  6 --
 net/xfrm/xfrm_user.c   | 23 +--
 5 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index df98463..01f5bc1 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -631,7 +631,8 @@ struct xfrm_mgr {
   u8 dir, u8 type,
   const struct xfrm_migrate *m,
   int num_bundles,
-  const struct xfrm_kmaddress *k);
+  const struct xfrm_kmaddress *k,
+  const struct xfrm_encap_tmpl *encap);
bool(*is_alive)(const struct km_event *c);
 };
 
@@ -1675,7 +1676,8 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, 
struct xfrm_policy *pol);
 #ifdef CONFIG_XFRM_MIGRATE
 int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
   const struct xfrm_migrate *m, int num_bundles,
-  const struct xfrm_kmaddress *k);
+  const struct xfrm_kmaddress *k,
+  const struct xfrm_encap_tmpl *encap);
 struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net 
*net);
 struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
  struct xfrm_migrate *m,
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 56df9fb..98c1ffb 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -3508,7 +3508,8 @@ static int set_ipsecrequest(struct sk_buff *skb,
 #ifdef CONFIG_NET_KEY_MIGRATE
 static int pfkey_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
  const struct xfrm_migrate *m, int num_bundles,
- const struct xfrm_kmaddress *k)
+ const struct xfrm_kmaddress *k,
+ const struct xfrm_encap_tmpl *encap)
 {
int i;
int sasize_sel;
@@ -3618,7 +3619,8 @@ static int pfkey_send_migrate(const struct xfrm_selector 
*sel, u8 dir, u8 type,
 #else
 static int pfkey_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
  const struct xfrm_migrate *m, int num_bundles,
- const struct xfrm_kmaddress *k)
+ const struct xfrm_kmaddress *k,
+ const struct xfrm_encap_tmpl *encap)
 {
return -ENOPROTOOPT;
 }
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index eaecfa4..7152147 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -3337,7 +3337,7 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, 
u8 type,
}
 
/* Stage 5 - announce */
-   km_migrate(sel, dir, type, m, num_migrate, k);
+   km_migrate(sel, dir, type, m, num_migrate, k, encap);
 
xfrm_pol_put(pol);
 
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index ae6206b..3f1c4a0 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1966,7 +1966,8 @@ EXPORT_SYMBOL(km_policy_expired);
 #ifdef CONFIG_XFRM_MIGRATE
 int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
   const struct xfrm_migrate *m, int num_migrate,
-  const struct xfrm_kmaddress *k)
+  const struct xfrm_kmaddress *k,
+  const struct xfrm_encap_tmpl *encap)
 {
int err = -EINVAL;
int ret;
@@ -1975,7 +1976,8 @@ int km_migrate(const struct xfrm_selector *sel, u8 dir, 
u8 type,
rcu_read_lock();
list_for_each_entry_rcu(km, &xfrm_km_list, list) {
if (km->migrate) {
-   ret = km->migrate(sel, dir, type, m, num_migrate, k);
+   ret = km->migrate(sel, dir, type, m, num_migrate, k,
+ encap);
if (!ret)
err = ret;
}
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index fb98892..6197c72 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -2314,17 +2314,20 @@ static int copy_to_user_kmaddress(const struct 
xfrm_kmaddress *k, struct sk_buff
return nla_put(skb, XFRMA_KMADDRESS, sizeof(uk), &uk);
 }
 
-static inline size_t xfrm_migrate_msgsize(int num_migrate, int 

[PATCH 2/2] xfrm: add UDP encapsulation port in migrate message

2017-06-05 Thread Antony Antony
Add XFRMA_ENCAP, UDP encapsulation port, to km_migrate announcement
to userland. Only add if XFRMA_ENCAP was in user migrate request.

Signed-off-by: Antony Antony 
---
 include/net/xfrm.h |  5 +++--
 net/key/af_key.c   |  3 ++-
 net/xfrm/xfrm_policy.c |  2 +-
 net/xfrm/xfrm_state.c  |  5 +++--
 net/xfrm/xfrm_user.c   | 23 +--
 5 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index df98463..9fb75fb 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -631,7 +631,8 @@ struct xfrm_mgr {
   u8 dir, u8 type,
   const struct xfrm_migrate *m,
   int num_bundles,
-  const struct xfrm_kmaddress *k);
+  const struct xfrm_kmaddress *k,
+  struct xfrm_encap_tmpl *encap);
bool(*is_alive)(const struct km_event *c);
 };
 
@@ -1675,7 +1676,7 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, 
struct xfrm_policy *pol);
 #ifdef CONFIG_XFRM_MIGRATE
 int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
   const struct xfrm_migrate *m, int num_bundles,
-  const struct xfrm_kmaddress *k);
+  const struct xfrm_kmaddress *k, struct xfrm_encap_tmpl *encap);
 struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net 
*net);
 struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
  struct xfrm_migrate *m,
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 56df9fb..2ad2286 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -3508,7 +3508,8 @@ static int set_ipsecrequest(struct sk_buff *skb,
 #ifdef CONFIG_NET_KEY_MIGRATE
 static int pfkey_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
  const struct xfrm_migrate *m, int num_bundles,
- const struct xfrm_kmaddress *k)
+ const struct xfrm_kmaddress *k,
+ struct xfrm_encap_tmpl *encap)
 {
int i;
int sasize_sel;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index eaecfa4..7152147 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -3337,7 +3337,7 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, 
u8 type,
}
 
/* Stage 5 - announce */
-   km_migrate(sel, dir, type, m, num_migrate, k);
+   km_migrate(sel, dir, type, m, num_migrate, k, encap);
 
xfrm_pol_put(pol);
 
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index ae6206b..d6220f7 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1966,7 +1966,7 @@ EXPORT_SYMBOL(km_policy_expired);
 #ifdef CONFIG_XFRM_MIGRATE
 int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
   const struct xfrm_migrate *m, int num_migrate,
-  const struct xfrm_kmaddress *k)
+  const struct xfrm_kmaddress *k, struct xfrm_encap_tmpl *encap)
 {
int err = -EINVAL;
int ret;
@@ -1975,7 +1975,8 @@ int km_migrate(const struct xfrm_selector *sel, u8 dir, 
u8 type,
rcu_read_lock();
list_for_each_entry_rcu(km, &xfrm_km_list, list) {
if (km->migrate) {
-   ret = km->migrate(sel, dir, type, m, num_migrate, k);
+   ret = km->migrate(sel, dir, type, m, num_migrate, k,
+ encap);
if (!ret)
err = ret;
}
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index fb98892..8c54484 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -2314,17 +2314,20 @@ static int copy_to_user_kmaddress(const struct 
xfrm_kmaddress *k, struct sk_buff
return nla_put(skb, XFRMA_KMADDRESS, sizeof(uk), &uk);
 }
 
-static inline size_t xfrm_migrate_msgsize(int num_migrate, int with_kma)
+static inline size_t xfrm_migrate_msgsize(int num_migrate, int with_kma,
+ int with_encp)
 {
return NLMSG_ALIGN(sizeof(struct xfrm_userpolicy_id))
  + (with_kma ? nla_total_size(sizeof(struct xfrm_kmaddress)) : 0)
+ + (with_encp ? nla_total_size(sizeof(struct xfrm_encap_tmpl)) : 0)
  + nla_total_size(sizeof(struct xfrm_user_migrate) * num_migrate)
  + userpolicy_type_attrsize();
 }
 
 static int build_migrate(struct sk_buff *skb, const struct xfrm_migrate *m,
 int num_migrate, const struct xfrm_kmaddress *k,
-const struct xfrm_selector *sel, u8 dir, u8 type)
+const struct xfrm_selector *sel,
+struct xfrm_encap_tmpl *encap, u8 dir, u8 type)

[PATCH 0/2] add udp encapsulation port to xfrm_do_migrate

2017-06-05 Thread Antony Antony
Currently xfrm_do_migrate only support migrating IP address.
This patches add UDP encapsulation port to xfrm_do_migrate.

The use case is for devices such as phones that support IKE MOBIKE.
Often when the device move from one network to the another or wake
up from sleep external NAT gateway IP address, port, or both could
change. With this patch xfrm_do_migrate will also support port change
if necessary.


Antony Antony (2):
  xfrm: extend MIGRATE with UDP encapsulation port
  xfrm: add UDP encapsulation port in migrate message

 include/net/xfrm.h | 11 +++
 net/key/af_key.c   |  5 +++--
 net/xfrm/xfrm_policy.c | 13 +
 net/xfrm/xfrm_state.c  | 23 ---
 net/xfrm/xfrm_user.c   | 37 +
 5 files changed, 60 insertions(+), 29 deletions(-)

-- 
2.9.3



[PATCH 1/2] xfrm: extend MIGRATE with UDP encapsulation port

2017-06-05 Thread Antony Antony
Add UDP encapsulation port to XFRM_MSG_MIGRATE using an optional
netlink attribute XFRMA_ENCAP.

The devices that support IKE MOBIKE extension (RFC-4555 Section 3.8)
could go to sleep for a few minutes and wake up. When it wake up the
NAT mapping could have expired, the device send a MOBIKE UPDATE_SA
message to migrate the IPsec SA. The change could be a change UDP
encapsulation port, IP address, or both.

Reported-by: Paul Wouters 
Signed-off-by: Antony Antony 
---
 include/net/xfrm.h |  6 --
 net/key/af_key.c   |  2 +-
 net/xfrm/xfrm_policy.c | 11 ---
 net/xfrm/xfrm_state.c  | 18 +-
 net/xfrm/xfrm_user.c   | 14 --
 5 files changed, 34 insertions(+), 17 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 7e7e2b0..df98463 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1678,10 +1678,12 @@ int km_migrate(const struct xfrm_selector *sel, u8 dir, 
u8 type,
   const struct xfrm_kmaddress *k);
 struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net 
*net);
 struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
- struct xfrm_migrate *m);
+ struct xfrm_migrate *m,
+ struct xfrm_encap_tmpl *encap);
 int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
 struct xfrm_migrate *m, int num_bundles,
-struct xfrm_kmaddress *k, struct net *net);
+struct xfrm_kmaddress *k, struct net *net,
+struct xfrm_encap_tmpl *encap);
 #endif
 
 int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 512dc43..56df9fb 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -2602,7 +2602,7 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff 
*skb,
}
 
return xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i,
-   kma ? &k : NULL, net);
+   kma ? &k : NULL, net, NULL);
 
  out:
return err;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index ed4e52d..eaecfa4 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -3268,11 +3268,6 @@ static int xfrm_migrate_check(const struct xfrm_migrate 
*m, int num_migrate)
return -EINVAL;
 
for (i = 0; i < num_migrate; i++) {
-   if (xfrm_addr_equal(&m[i].old_daddr, &m[i].new_daddr,
-   m[i].old_family) &&
-   xfrm_addr_equal(&m[i].old_saddr, &m[i].new_saddr,
-   m[i].old_family))
-   return -EINVAL;
if (xfrm_addr_any(&m[i].new_daddr, m[i].new_family) ||
xfrm_addr_any(&m[i].new_saddr, m[i].new_family))
return -EINVAL;
@@ -3296,7 +3291,8 @@ static int xfrm_migrate_check(const struct xfrm_migrate 
*m, int num_migrate)
 
 int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
 struct xfrm_migrate *m, int num_migrate,
-struct xfrm_kmaddress *k, struct net *net)
+struct xfrm_kmaddress *k, struct net *net,
+struct xfrm_encap_tmpl *encap)
 {
int i, err, nx_cur = 0, nx_new = 0;
struct xfrm_policy *pol = NULL;
@@ -3319,7 +3315,8 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, 
u8 type,
if ((x = xfrm_migrate_state_find(mp, net))) {
x_cur[nx_cur] = x;
nx_cur++;
-   if ((xc = xfrm_state_migrate(x, mp))) {
+   xc = xfrm_state_migrate(x, mp, encap);
+   if (xc) {
x_new[nx_new] = xc;
nx_new++;
} else {
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 2e291bc..ae6206b 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1309,7 +1309,8 @@ int xfrm_state_add(struct xfrm_state *x)
 EXPORT_SYMBOL(xfrm_state_add);
 
 #ifdef CONFIG_XFRM_MIGRATE
-static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig)
+static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
+  struct xfrm_encap_tmpl *encap)
 {
struct net *net = xs_net(orig);
struct xfrm_state *x = xfrm_state_alloc(net);
@@ -1351,8 +1352,14 @@ static struct xfrm_state *xfrm_state_clone(struct 
xfrm_state *orig)
}
x->props.calgo = orig->props.calgo;
 
-   if (orig->encap) {
-   x->encap = kmemdup(orig->encap, sizeof(*x->encap), GFP_KERNEL);
+   if (encap || orig->encap) {
+   if (encap)
+   x->encap = kmemdup(encap, sizeof(*x->encap),

[PATCH v2] xfrm: fix state migration copy replay sequence numbers

2017-05-19 Thread Antony Antony
During xfrm migration copy replay and preplay sequence numbers
from the previous state.

Here is a tcpdump output showing the problem.
10.0.10.46 is running vanilla kernel, is the IKE/IPsec responder.
After the migration it sent wrong sequence number, reset to 1.
The migration is from 10.0.0.52 to 10.0.0.53.

IP 10.0.0.52.4500 > 10.0.10.46.4500: UDP-encap: ESP(spi=0x43ef462d,seq=0x7cf), 
length 136
IP 10.0.10.46.4500 > 10.0.0.52.4500: UDP-encap: ESP(spi=0xca1c282d,seq=0x7cf), 
length 136
IP 10.0.0.52.4500 > 10.0.10.46.4500: UDP-encap: ESP(spi=0x43ef462d,seq=0x7d0), 
length 136
IP 10.0.10.46.4500 > 10.0.0.52.4500: UDP-encap: ESP(spi=0xca1c282d,seq=0x7d0), 
length 136

IP 10.0.0.53.4500 > 10.0.10.46.4500: NONESP-encap: isakmp: child_sa  inf2[I]
IP 10.0.10.46.4500 > 10.0.0.53.4500: NONESP-encap: isakmp: child_sa  inf2[R]
IP 10.0.0.53.4500 > 10.0.10.46.4500: NONESP-encap: isakmp: child_sa  inf2[I]
IP 10.0.10.46.4500 > 10.0.0.53.4500: NONESP-encap: isakmp: child_sa  inf2[R]

IP 10.0.0.53.4500 > 10.0.10.46.4500: UDP-encap: ESP(spi=0x43ef462d,seq=0x7d1), 
length 136

NOTE: next sequence is wrong 0x1

IP 10.0.10.46.4500 > 10.0.0.53.4500: UDP-encap: ESP(spi=0xca1c282d,seq=0x1), 
length 136
IP 10.0.0.53.4500 > 10.0.10.46.4500: UDP-encap: ESP(spi=0x43ef462d,seq=0x7d2), 
length 136
IP 10.0.10.46.4500 > 10.0.0.53.4500: UDP-encap: ESP(spi=0xca1c282d,seq=0x2), 
length 136

Signed-off-by: Antony Antony 
---
Changes in v2:
  - include tcpdump output showing the problem in the commit message.

 net/xfrm/xfrm_state.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index fc3c5aa..2e291bc 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1383,6 +1383,8 @@ static struct xfrm_state *xfrm_state_clone(struct 
xfrm_state *orig)
x->curlft.add_time = orig->curlft.add_time;
x->km.state = orig->km.state;
x->km.seq = orig->km.seq;
+   x->replay = orig->replay;
+   x->preplay = orig->preplay;
 
return x;
 
-- 
2.9.3



[PATCH] xfrm: fix state migration replay sequence numbers

2017-05-18 Thread Antony Antony
During xfrm migration replay and preplay sequence numbers are not 
copied from the previous state. 

Here is tcpdump output showing the problem.
10.0.10.46 is running vanilla kernel, IKE/IPsec responder.
After the migration it sent wrong sequence number, reset to 1.
The migration is from 10.0.0.52 to 10.0.0.53.

IP 10.0.0.52.4500 > 10.0.10.46.4500: UDP-encap: ESP(spi=0x43ef462d,seq=0x7cf), 
length 136
IP 10.0.10.46.4500 > 10.0.0.52.4500: UDP-encap: ESP(spi=0xca1c282d,seq=0x7cf), 
length 136
IP 10.0.0.52.4500 > 10.0.10.46.4500: UDP-encap: ESP(spi=0x43ef462d,seq=0x7d0), 
length 136
IP 10.0.10.46.4500 > 10.0.0.52.4500: UDP-encap: ESP(spi=0xca1c282d,seq=0x7d0), 
length 136

IP 10.0.0.53.4500 > 10.0.10.46.4500: NONESP-encap: isakmp: child_sa  inf2[I]
IP 10.0.10.46.4500 > 10.0.0.53.4500: NONESP-encap: isakmp: child_sa  inf2[R]
IP 10.0.0.53.4500 > 10.0.10.46.4500: NONESP-encap: isakmp: child_sa  inf2[I]
IP 10.0.10.46.4500 > 10.0.0.53.4500: NONESP-encap: isakmp: child_sa  inf2[R]

IP 10.0.0.53.4500 > 10.0.10.46.4500: UDP-encap: ESP(spi=0x43ef462d,seq=0x7d1), 
length 136

NOTE: next sequence is wrong 0x1

IP 10.0.10.46.4500 > 10.0.0.53.4500: UDP-encap: ESP(spi=0xca1c282d,seq=0x1), 
length 136
IP 10.0.0.53.4500 > 10.0.10.46.4500: UDP-encap: ESP(spi=0x43ef462d,seq=0x7d2), 
length 136
IP 10.0.10.46.4500 > 10.0.0.53.4500: UDP-encap: ESP(spi=0xca1c282d,seq=0x2), 
length 136

The attached patch fix it by copying replay and preplay.

regards,
-antony

Antony Antony (1):
  xfrm: fix state migration replay sequence numbers

 net/xfrm/xfrm_state.c | 2 ++
 1 file changed, 2 insertions(+)

-- 
2.9.3

>From 1241e8b4c38ad2bf7399599165f763af38aba8d9 Mon Sep 17 00:00:00 2001
From: Antony Antony 
Date: Thu, 18 May 2017 12:19:32 +0200
Subject: [PATCH] xfrm: fix state migration copy replay sequence numbers
To: netdev@vger.kernel.org, Herbert Xu , Steffen 
Klassert 
Cc: Richard Guy Briggs 

During xfrm migration copy replay and preplay sequence numbers
from the previous state.

Signed-off-by: Antony Antony 
---
 net/xfrm/xfrm_state.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index fc3c5aa..2e291bc 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1383,6 +1383,8 @@ static struct xfrm_state *xfrm_state_clone(struct 
xfrm_state *orig)
x->curlft.add_time = orig->curlft.add_time;
x->km.state = orig->km.state;
x->km.seq = orig->km.seq;
+   x->replay = orig->replay;
+   x->preplay = orig->preplay;
 
return x;
 
-- 
2.9.3