ipsec: fix IPv4 AH alignment on 32 bits
Subsystems (3)
RFC PATCH 1/1 ipsec: fix IPv4 AH alignment on 32 bits
Hi,
here is a patch to fix alignment of IPv4 AH. Note that this break compatiblity for some algorithms (like SHA256) with old kernels ... but upstream cannot use SHA256 on IPv4, for example, with a target that is RFC compliant.
I don't know what is the best way to fix this.
Regards,
Nicolas
Quoted 1 line
From
14bbe173eed25cf59e3e54222eb7de1a5578e54eMon Sep 17 00:00:00 2001
From: Dang Hongwu <[email protected]>
Date: Wed, 22 Dec 2010 11:38:47 -0500
Subject: [PATCH] ipsec: fix IPv4 AH alignment on 32 bits
The Linux IPv4 AH stack aligns the AH header on a 64 bit boundary (like in IPv6). This is not RFC compliant (see RFC4302, Section 3.3.3.2.1), it should be aligned on 32 bits.
For most of the authentication algorithms, the ICV size is 96 bits. The AH header alignment on 32 or 64 bits gives the same results.
However for SHA-256-128 for instance, the wrong 64 bit alignment results in adding useless padding in IPv4 AH, which is forbidden by the RFC.
--- include/net/xfrm.h | 1 + net/ipv4/ah4.c | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-)
include/net/xfrm.h +1 -0
@@ -36,6 +36,7 @@#define XFRM_PROTO_ROUTING IPPROTO_ROUTING#define XFRM_PROTO_DSTOPTS IPPROTO_DSTOPTS +#define XFRM_ALIGN4 (len) (((len) + 3) & ~3)#define XFRM_ALIGN8 (len) (((len) + 7) & ~7)#define MODULE_ALIAS_XFRM_MODE (family, encap) \ MODULE_ALIAS("xfrm-mode-" __stringify(family) "-" __stringify(encap))
net/ipv4/ah4.c +4 -4
@@ -201,7 +201,7 @@ static int ah_output(struct xfrm_state *x, struct sk_buff *skb) top_iph->ttl =0 ; top_iph->check =0 ; - ah->hdrlen = (XFRM_ALIGN8 (sizeof (*ah) + ahp->icv_trunc_len) >>2 ) -2 ; + ah->hdrlen = (XFRM_ALIGN4 (sizeof (*ah) + ahp->icv_trunc_len) >>2 ) -2 ; ah->reserved =0 ; ah->spi = x->id.spi;
@@ -299,8 +299,8 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb) nexthdr = ah->nexthdr; ah_hlen = (ah->hdrlen +2 ) <<2 ; -if (ah_hlen !=XFRM_ALIGN8 (sizeof (*ah) + ahp->icv_full_len) && - ah_hlen !=XFRM_ALIGN8 (sizeof (*ah) + ahp->icv_trunc_len)) +if (ah_hlen !=XFRM_ALIGN4 (sizeof (*ah) + ahp->icv_full_len) && + ah_hlen !=XFRM_ALIGN4 (sizeof (*ah) + ahp->icv_trunc_len)) goto out;if (!pskb_may_pull (skb, ah_hlen))
@@ -450,7 +450,7 @@ static int ah_init_state(struct xfrm_state *x)BUG_ON (ahp->icv_trunc_len >MAX_AH_AUTH_LEN ); - x->props.header_len =XFRM_ALIGN8 (sizeof (struct ip_auth_hdr ) + + x->props.header_len =XFRM_ALIGN4 (sizeof (struct ip_auth_hdr ) + ahp->icv_trunc_len);if (x->props.mode ==XFRM_MODE_TUNNEL ) x->props.header_len +=sizeof (struct iphdr );
Signature · 1 line
1.5.6.5
David Miller
maintainerFrom: Nicolas Dichtel <[email protected]>
Date: Thu, 13 Jan 2011 18:20:19 +0100
Quoted 6 lines
here is a patch to fix alignment of IPv4 AH. Note that this break compatiblity for some algorithms (like SHA256) with old kernels ... but upstream cannot use SHA256 on IPv4, for example, with a target that is RFC compliant.
I don't know what is the best way to fix this.
We cannot just start rejecting the old 8-byte alignment on input if Linux has been using an 8-byte alignment since day one.
If you want this change to be considered seriously, you need to relax the AH4 input check.
Herbert Xu
maintainerQuoted 6 lines · David Miller
We cannot just start rejecting the old 8-byte alignment on input if Linux has been using an 8-byte alignment since day one.
If you want this change to be considered seriously, you need to relax the AH4 input check.
I second your sentiment. However, in this particular case it would appear that our old implementation was also overly strict in rejecting 32-bit alignment so even if we relax it now it still wouldn't work with an old implementation once we reduce the padding on output (unless you traffic was one-way only).
So perhaps an SA configuration flag is needed?
Cheers,
Signature · 3 lines
Email: Herbert Xu <[email protected]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Quoted 5 lines · Herbert Xu
Quoted 4 lines · David Miller
We cannot just start rejecting the old 8-byte alignment on input if Linux has been using an 8-byte alignment since day one.
Quoted 8 lines
Quoted 2 lines
If you want this change to be considered seriously, you need to relax the AH4 input check.
I second your sentiment. However, in this particular case it would appear that our old implementation was also overly strict in rejecting 32-bit alignment so even if we relax it now it still wouldn't work with an old implementation once we reduce the padding on output (unless you traffic was one-way only).
Yes, this was my initial problem.
Quoted 2 lines
So perhaps an SA configuration flag is needed?
I agree. If David is ok, I will update the patch.
Regards,
Nicolas
David Miller
maintainerFrom: Nicolas Dichtel <[email protected]>
Date: Fri, 28 Jan 2011 09:51:40 +0100
Quoted 3 lines · Herbert Xu
Quoted 1 line
So perhaps an SA configuration flag is needed?
I agree. If David is ok, I will update the patch.
Sounds good to me.
PATCH 1/1 ipsec: allow to align IPv4 AH on 32 bits
Quoted 8 lines · David Miller
From: Nicolas Dichtel<[email protected]>
Date: Fri, 28 Jan 2011 09:51:40 +0100Quoted 3 lines · Herbert Xu
Quoted 1 line
So perhaps an SA configuration flag is needed?
I agree. If David is ok, I will update the patch.
Sounds good to me.
Here is the new patch.
The patch for iproute2 in the next email.
Regards,
Nicolas
Quoted 1 line
From
1772aa5401b24f4cb4cc10b038becdeb2c687531Mon Sep 17 00:00:00 2001
From: Dang Hongwu <[email protected]>
Date: Wed, 22 Dec 2010 11:38:47 -0500
Subject: [PATCH] ipsec: allow to align IPv4 AH on 32 bits
The Linux IPv4 AH stack aligns the AH header on a 64 bit boundary (like in IPv6). This is not RFC compliant (see RFC4302, Section 3.3.3.2.1), it should be aligned on 32 bits.
For most of the authentication algorithms, the ICV size is 96 bits. The AH header alignment on 32 or 64 bits gives the same results.
However for SHA-256-128 for instance, the wrong 64 bit alignment results in adding useless padding in IPv4 AH, which is forbidden by the RFC.
To avoid breaking backward compatibility, we use a new flag (XFRM_STATE_ALIGN4) do change original behavior.
Initial patch from Dang Hongwu <[email protected]> and Christophe Gouault <[email protected]>.
--- include/linux/xfrm.h | 1 + include/net/xfrm.h | 1 + net/ipv4/ah4.c | 25 +++++++++++++++++++------ 3 files changed, 21 insertions(+), 6 deletions(-)
include/linux/xfrm.h +1 -0
@@ -350,6 +350,7 @@ struct xfrm_usersa_info {#define XFRM_STATE_WILDRECV 8#define XFRM_STATE_ICMP 16#define XFRM_STATE_AF_UNSPEC 32 +#define XFRM_STATE_ALIGN4 64 };struct xfrm_usersa_id {
include/net/xfrm.h +1 -0
@@ -36,6 +36,7 @@#define XFRM_PROTO_ROUTING IPPROTO_ROUTING#define XFRM_PROTO_DSTOPTS IPPROTO_DSTOPTS +#define XFRM_ALIGN4 (len) (((len) + 3) & ~3)#define XFRM_ALIGN8 (len) (((len) + 7) & ~7)#define MODULE_ALIAS_XFRM_MODE (family, encap) \ MODULE_ALIAS("xfrm-mode-" __stringify(family) "-" __stringify(encap))
net/ipv4/ah4.c +19 -6
@@ -201,7 +201,10 @@ static int ah_output(struct xfrm_state *x, struct sk_buff *skb) top_iph->ttl =0 ; top_iph->check =0 ; - ah->hdrlen = (XFRM_ALIGN8 (sizeof (*ah) + ahp->icv_trunc_len) >>2 ) -2 ; +if (x->props.flags &XFRM_STATE_ALIGN4 ) + ah->hdrlen = (XFRM_ALIGN4 (sizeof (*ah) + ahp->icv_trunc_len) >>2 ) -2 ; +else + ah->hdrlen = (XFRM_ALIGN8 (sizeof (*ah) + ahp->icv_trunc_len) >>2 ) -2 ; ah->reserved =0 ; ah->spi = x->id.spi;
@@ -299,9 +302,15 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb) nexthdr = ah->nexthdr; ah_hlen = (ah->hdrlen +2 ) <<2 ; -if (ah_hlen !=XFRM_ALIGN8 (sizeof (*ah) + ahp->icv_full_len) && - ah_hlen !=XFRM_ALIGN8 (sizeof (*ah) + ahp->icv_trunc_len)) - goto out; +if (x->props.flags &XFRM_STATE_ALIGN4 ) { +if (ah_hlen !=XFRM_ALIGN4 (sizeof (*ah) + ahp->icv_full_len) && + ah_hlen !=XFRM_ALIGN4 (sizeof (*ah) + ahp->icv_trunc_len)) + goto out; + }else { +if (ah_hlen !=XFRM_ALIGN8 (sizeof (*ah) + ahp->icv_full_len) && + ah_hlen !=XFRM_ALIGN8 (sizeof (*ah) + ahp->icv_trunc_len)) + goto out; + }if (!pskb_may_pull (skb, ah_hlen)) goto out;
@@ -450,8 +459,12 @@ static int ah_init_state(struct xfrm_state *x)BUG_ON (ahp->icv_trunc_len >MAX_AH_AUTH_LEN ); - x->props.header_len =XFRM_ALIGN8 (sizeof (struct ip_auth_hdr ) + - ahp->icv_trunc_len); +if (x->props.flags &XFRM_STATE_ALIGN4 ) + x->props.header_len =XFRM_ALIGN4 (sizeof (struct ip_auth_hdr ) + + ahp->icv_trunc_len); +else + x->props.header_len =XFRM_ALIGN8 (sizeof (struct ip_auth_hdr ) + + ahp->icv_trunc_len);if (x->props.mode ==XFRM_MODE_TUNNEL ) x->props.header_len +=sizeof (struct iphdr ); x->data = ahp;
Signature · 1 line
1.5.6.5
Re: [PATCH] ipsec: allow to align IPv4 AH on 32 bits
From: Nicolas Dichtel <[email protected]>
Date: Wed, 02 Feb 2011 17:29:02 +0100
Quoted 11 lines · David Miller
Quoted 8 lines
From: Nicolas Dichtel<[email protected]>
Date: Fri, 28 Jan 2011 09:51:40 +0100Quoted 3 lines · Herbert Xu
Quoted 1 line
So perhaps an SA configuration flag is needed?
I agree. If David is ok, I will update the patch.
Sounds good to me.
Here is the new patch.
I've applied this to net-next-2.6, thanks.
PATCH 1/1 iproute2: allow to specify truncation bits on auth algo
In reply to David MillerQuoted 8 lines · David Miller
From: Nicolas Dichtel<[email protected]>
Date: Fri, 28 Jan 2011 09:51:40 +0100Quoted 3 lines · Herbert Xu
Quoted 1 line
So perhaps an SA configuration flag is needed?
I agree. If David is ok, I will update the patch.
Sounds good to me.
And the patch for iproute2.
Regards,
Nicolas
Quoted 1 line
From
e0d84548d363cfa46a03719bc318ef52fa5ca98fMon Sep 17 00:00:00 2001
From: Nicolas Dichtel <[email protected]>
Date: Thu, 23 Dec 2010 06:48:12 -0500
Subject: [PATCH] iproute2: allow to specify truncation bits on auth algo
Attribute XFRMA_ALG_AUTH_TRUNC can be used to specify truncation bits, so we add a new algo type: auth-trunc.
--- ip/ipxfrm.c | 28 +++++++++++++++++++++++++++- ip/xfrm_state.c | 50 +++++++++++++++++++++++++++++++++----------------- 2 files changed, 60 insertions(+), 18 deletions(-)
ip/ipxfrm.c +27 -1
@@ -155,6 +155,7 @@ const char *strxf_xfrmproto(__u8 proto)static const struct typeent algo_types[]= { {"enc" ,XFRMA_ALG_CRYPT }, {"auth" ,XFRMA_ALG_AUTH }, {"comp" ,XFRMA_ALG_COMP }, {"aead" ,XFRMA_ALG_AEAD }, + {"auth-trunc" ,XFRMA_ALG_AUTH_TRUNC }, {NULL ,-1 } };
@@ -570,6 +571,25 @@ static void xfrm_aead_print(struct xfrm_algo_aead *algo, int len,fprintf (fp,"%s" , _SL_); } +static void xfrm_auth_trunc_print (struct xfrm_algo_auth *algo,int len, +FILE *fp,const char *prefix) +{ +struct { +struct xfrm_algo algo; +char key[algo->alg_key_len /8 ]; + } base; + +memcpy (base.algo.alg_name, algo->alg_name,sizeof (base.algo.alg_name)); + base.algo.alg_key_len = algo->alg_key_len; +memcpy (base.algo.alg_key, algo->alg_key, algo->alg_key_len /8 ); + +__xfrm_algo_print (&base.algo,XFRMA_ALG_AUTH_TRUNC , len, fp, prefix,0 ); + +fprintf (fp," %d" , algo->alg_trunc_len); + +fprintf (fp,"%s" , _SL_); +} +static void xfrm_tmpl_print (struct xfrm_user_tmpl *tmpls,int len,__u16 family,FILE *fp,const char *prefix) {
@@ -677,12 +697,18 @@ void xfrm_xfrma_print(struct rtattr *tb[], __u16 family,fprintf (fp,"\tmark %d/0x%x\n" , m->v, m->m); } -if (tb[XFRMA_ALG_AUTH ]) { +if (tb[XFRMA_ALG_AUTH ] && !tb[XFRMA_ALG_AUTH_TRUNC ]) {struct rtattr *rta = tb[XFRMA_ALG_AUTH ];xfrm_algo_print ((struct xfrm_algo *)RTA_DATA (rta),XFRMA_ALG_AUTH ,RTA_PAYLOAD (rta), fp, prefix); } +if (tb[XFRMA_ALG_AUTH_TRUNC ]) { +struct rtattr *rta = tb[XFRMA_ALG_AUTH_TRUNC ]; +xfrm_auth_trunc_print ((struct xfrm_algo_auth *)RTA_DATA (rta), +RTA_PAYLOAD (rta), fp, prefix); + } +if (tb[XFRMA_ALG_AEAD ]) {struct rtattr *rta = tb[XFRMA_ALG_AEAD ]; xfrm_aead_print((struct xfrm_algo_aead *)RTA_DATA(rta),
ip/xfrm_state.c +33 -17
95 lines not on this page · raw message
Signature · 1 line
1.5.6.5
Re: [PATCH] iproute2: allow to specify truncation bits on auth algo
Quoted 10 lines · Nicolas Dichtel
Quoted 8 lines · David Miller
From: Nicolas Dichtel<[email protected]>
Date: Fri, 28 Jan 2011 09:51:40 +0100Quoted 3 lines · Herbert Xu
Quoted 1 line
So perhaps an SA configuration flag is needed?
I agree. If David is ok, I will update the patch.
Sounds good to me.
And the patch for iproute2.
Sorry, two patches were mixed :(
Here is the right one.
Regards,
Nicolas
Quoted 1 line
From
fe61b9c3564b2f9504bca652cdea80ff3b5a2743Mon Sep 17 00:00:00 2001
From: Nicolas Dichtel <[email protected]>
Date: Tue, 1 Feb 2011 07:29:54 -0500
Subject: [PATCH] iproute2: add support of flag XFRM_STATE_ALIGN4
--- include/linux/xfrm.h | 1 + ip/ipxfrm.c | 1 + ip/xfrm_state.c | 4 +++- 3 files changed, 5 insertions(+), 1 deletions(-)
include/linux/xfrm.h +1 -0
@@ -349,6 +349,7 @@ struct xfrm_usersa_info {#define XFRM_STATE_WILDRECV 8#define XFRM_STATE_ICMP 16#define XFRM_STATE_AF_UNSPEC 32 +#define XFRM_STATE_ALIGN4 64 };struct xfrm_usersa_id {
ip/ipxfrm.c +1 -0
@@ -828,6 +828,7 @@ void xfrm_state_info_print(struct xfrm_usersa_info *xsinfo,XFRM_FLAG_PRINT (fp, flags,XFRM_STATE_WILDRECV ,"wildrecv" );XFRM_FLAG_PRINT (fp, flags,XFRM_STATE_ICMP ,"icmp" );XFRM_FLAG_PRINT (fp, flags,XFRM_STATE_AF_UNSPEC ,"af-unspec" ); +XFRM_FLAG_PRINT (fp, flags,XFRM_STATE_ALIGN4 ,"align4" );if (flags)fprintf (fp,"%x" , flags); }
ip/xfrm_state.c +3 -1
@@ -83,7 +83,7 @@ static void usage(void)//fprintf(stderr, "REQID - number(default=0)\n"); fprintf (stderr,"FLAG-LIST := [ FLAG-LIST ] FLAG\n" ); -fprintf (stderr,"FLAG := [ noecn | decap-dscp | nopmtudisc | wildrecv | icmp | af-unspec ]\n" ); +fprintf (stderr,"FLAG := [ noecn | decap-dscp | nopmtudisc | wildrecv | icmp | af-unspec | align4 ]\n" );fprintf (stderr,"ENCAP := ENCAP-TYPE SPORT DPORT OADDR\n" );fprintf (stderr,"ENCAP-TYPE := espinudp | espinudp-nonike\n" );
@@ -214,6 +214,8 @@ static int xfrm_state_flag_parse(__u8 *flags, int *argcp, char ***argvp) *flags |=XFRM_STATE_ICMP ; else if (strcmp(*argv, "af-unspec") == 0) *flags |=XFRM_STATE_AF_UNSPEC ; + else if (strcmp(*argv, "align4") == 0) + *flags |= XFRM_STATE_ALIGN4; else {PREV_ARG ();/* back track */ break ;
Signature · 1 line
1.5.6.5
Re: [PATCH] iproute2: allow to specify truncation bits on auth algo
Hi,
what is the status of this patch? It has been set to 'Superseded' in the patchwork tool (http://patchwork.ozlabs.org/patch/81486/).
Kernel headers have been updated in iproute2, should I resend the patch?
Regards,
Nicolas
Quoted 18 lines · Nicolas Dichtel
Quoted 10 lines · Nicolas Dichtel
Quoted 8 lines · David Miller
From: Nicolas Dichtel<[email protected]>
Date: Fri, 28 Jan 2011 09:51:40 +0100Quoted 3 lines · Herbert Xu
Quoted 1 line
So perhaps an SA configuration flag is needed?
I agree. If David is ok, I will update the patch.
Sounds good to me.
And the patch for iproute2.
Sorry, two patches were mixed :(
Here is the right one.
Regards,
Nicolas
Re: [PATCH] iproute2: allow to specify truncation bits on auth algo
It is in net-next branch of iproute