Received: with ECARTIS (v1.0.0; list netdev); Thu, 30 Dec 2004 00:47:55 -0800 (PST) Received: from smtp.knology.net (smtp.knology.net [24.214.63.101]) by oss.sgi.com (8.13.0/8.13.0) with SMTP id iBU8kP5F024577 for ; Thu, 30 Dec 2004 00:46:45 -0800 Received: (qmail 28275 invoked by uid 0); 30 Dec 2004 08:49:00 -0000 Received: from user-69-1-45-93.knology.net (HELO ori.thedillows.org) (69.1.45.93) by smtp2.knology.net with SMTP; 30 Dec 2004 08:49:00 -0000 Received: from ori.thedillows.org (localhost [127.0.0.1]) by ori.thedillows.org (8.13.1/8.13.1) with ESMTP id iBU8mbN8009827; Thu, 30 Dec 2004 03:48:37 -0500 Received: (from root@localhost) by ori.thedillows.org (8.13.1/8.13.1/Submit) id iBU8mbGL009826; Thu, 30 Dec 2004 03:48:37 -0500 Date: Thu, 30 Dec 2004 03:48:37 -0500 To: netdev@oss.sgi.com Cc: linux-kernel@vger.kernel.org, dave@thedillows.org From: David Dillow Subject: [RFC 2.6.10 18/22] typhoon: add validation of offloaded xfrm_states Message-Id: <20041230035000.27@ori.thedillows.org> References: <20041230035000.26@ori.thedillows.org> X-Virus-Scanned: ClamAV 0.80/638/Tue Dec 21 14:41:34 2004 clamav-milter version 0.80j on 127.0.0.1 X-Virus-Status: Clean X-archive-position: 13220 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: dave@thedillows.org Precedence: bulk X-list: netdev # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/12/30 01:00:43-05:00 dave@thedillows.org # Add routines to validate that the xfrm_state passed to them is # one that we can offload to the 3XP. # # Signed-off-by: David Dillow # # drivers/net/typhoon.c # 2004/12/30 01:00:25-05:00 dave@thedillows.org +90 -0 # Add routines to validate that the xfrm_state passed to them is # one that we can offload to the 3XP. # # Signed-off-by: David Dillow # diff -Nru a/drivers/net/typhoon.c b/drivers/net/typhoon.c --- a/drivers/net/typhoon.c 2004-12-30 01:08:32 -05:00 +++ b/drivers/net/typhoon.c 2004-12-30 01:08:32 -05:00 @@ -2330,6 +2330,96 @@ return 0; } +#define UNSUPPORTED goto unsupported +#define REQUIRED(x) if(!(x)) goto unsupported + +static inline int +typhoon_validate_ealgo(struct typhoon *tp, struct xfrm_state *x) +{ + switch(x->props.ealgo) { + case SADB_EALG_NULL: + break; + case SADB_EALG_DESCBC: + REQUIRED(x->ealg); + REQUIRED(tp->capabilities & TYPHOON_CRYPTO_DES); + REQUIRED(x->ealg->alg_key_len == 64); + break; + case SADB_EALG_3DESCBC: + REQUIRED(x->ealg); + REQUIRED(tp->capabilities & TYPHOON_CRYPTO_3DES); + REQUIRED(x->ealg->alg_key_len == 128 || + x->ealg->alg_key_len == 192); + break; + default: + UNSUPPORTED; + } + + return 1; + +unsupported: + return 0; +} + +static inline int +typhoon_validate_aalgo(struct typhoon *tp, struct xfrm_state *x) +{ + switch(x->props.aalgo) { + case SADB_X_AALG_NULL: + break; + case SADB_AALG_MD5HMAC: + REQUIRED(x->aalg); + REQUIRED(x->aalg->alg_key_len == 128); + break; + case SADB_AALG_SHA1HMAC: + REQUIRED(x->aalg); + REQUIRED(x->aalg->alg_key_len == 160); + break; + default: + UNSUPPORTED; + } + + return 1; + +unsupported: + return 0; +} + +static inline int +typhoon_validate_xfrm(struct typhoon *tp, struct xfrm_state *x) +{ + u8 ealgo, aalgo, need_auth = 1; + + REQUIRED(x->props.family == AF_INET); + REQUIRED(x->dir == XFRM_STATE_DIR_OUT || x->dir == XFRM_STATE_DIR_IN); + REQUIRED(!x->encap); + + aalgo = x->props.aalgo; + ealgo = x->props.ealgo; + + switch(x->type->proto) { + case IPPROTO_ESP: + need_auth = 0; + REQUIRED(aalgo != SADB_X_AALG_NULL || ealgo != SADB_EALG_NULL); + REQUIRED(typhoon_validate_ealgo(tp, x)); + /* fall through to validate auth algorithm */ + case IPPROTO_AH: + REQUIRED(typhoon_validate_aalgo(tp, x)); + if(need_auth) + REQUIRED(aalgo != SADB_X_AALG_NULL); + break; + default: + UNSUPPORTED; + } + + return 1; + +unsupported: + return 0; +} + +#undef REQUIRED +#undef UNSUPPORTED + static void typhoon_tx_timeout(struct net_device *dev) {