From patchwork Tue Sep 1 12:23:21 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Badea X-Patchwork-Id: 32742 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@bilbo.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from ozlabs.org (ozlabs.org [203.10.76.45]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "mx.ozlabs.org", Issuer "CA Cert Signing Authority" (verified OK)) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4660EB7C26 for ; Tue, 1 Sep 2009 22:23:38 +1000 (EST) Received: by ozlabs.org (Postfix) id 387C6DDD0B; Tue, 1 Sep 2009 22:23:38 +1000 (EST) Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id 3B0C9DDD04 for ; Tue, 1 Sep 2009 22:23:37 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754307AbZIAMX0 (ORCPT ); Tue, 1 Sep 2009 08:23:26 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754253AbZIAMXZ (ORCPT ); Tue, 1 Sep 2009 08:23:25 -0400 Received: from ixro-out-rtc.ixiacom.com ([92.87.192.98]:27577 "EHLO ixro-ex1.ixiacom.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753799AbZIAMXX (ORCPT ); Tue, 1 Sep 2009 08:23:23 -0400 Received: from [10.205.20.102] ([10.205.20.102]) by ixro-ex1.ixiacom.com with Microsoft SMTPSVC(6.0.3790.3959); Tue, 1 Sep 2009 15:23:22 +0300 Message-ID: <4A9D1239.8000900@ixiacom.com> Date: Tue, 01 Sep 2009 15:23:21 +0300 From: Alex Badea User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.23) Gecko/20090812 Thunderbird/2.0.0.23 Mnenhy/0.7.5.0 MIME-Version: 1.0 To: Steffen Klassert CC: Herbert Xu , djenkins@mvista.com, linux-crypto@vger.kernel.org, netdev@vger.kernel.org Subject: Re: Does ESP support 64 bit sequence numbering for authentication hash ? References: <1231943033.7937.120.camel@libdev3.mvista.co.uk> <20090115055644.GA30626@gondor.apana.org.au> <20090901120915.GA12646@secunet.com> In-Reply-To: <20090901120915.GA12646@secunet.com> X-Enigmail-Version: 0.96.0 X-OriginalArrivalTime: 01 Sep 2009 12:23:22.0809 (UTC) FILETIME=[FF610A90:01CA2AFE] Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org On 09/01/2009 03:09 PM, Steffen Klassert wrote: > On Thu, Jan 15, 2009 at 04:56:44PM +1100, Herbert Xu wrote: >> Dean Jenkins wrote: >>> Does ESP support 64 bit sequence numbering for use with the >>> authentication HMAC ? >> We don't support 64-bit sequence numbers yet. If you look at >> struct xfrm_replay_state which is where we store the sequence >> number internally you'll find that it uses u32s. >> >> Patches for 64-bit support are welcome of course. >> > > Is there actually anybody working on 64-bit sequence number support? > If not, I'd start to look at it. A while ago I implemented a rough version of ESN support. It's against an ancient 2.6.7 kernel though, and is only superficially tested. I suppose there's no reason not to publish them here, if only for historical reasons. My apologies to anyone not interested :) Alex Badea (6): xfrm: move xfrm_replay_{check,advance} to their own source file xfrm: introduce XFRM_STATE_ESN flag, and extended replay structure xfrm: add generic support for replay protection with Extended Sequence Numbers ipsec: Extended Sequence Numbers support for ESP ipsec: Extended Sequence Numbers support for AH xfrm: add test harness for Extended Sequence Numbers replay protection algorithm Best regards, Alex From 813d3e12e5f207d037bb1570a35519da77227f0e Mon Sep 17 00:00:00 2001 From: Alex Badea Date: Mon, 29 Jun 2009 12:29:25 +0300 Subject: [PATCH] xfrm: add test harness for Extended Sequence Numbers replay protection algorithm --- test/esn/SConstruct | 15 +++ test/esn/harness.c | 257 +++++++++++++++++++++++++++++++++++++++++++++++++++ test/esn/harness.h | 37 ++++++++ 3 files changed, 309 insertions(+), 0 deletions(-) create mode 100644 test/esn/SConstruct create mode 100644 test/esn/harness.c create mode 100644 test/esn/harness.h diff --git a/test/esn/SConstruct b/test/esn/SConstruct new file mode 100644 index 0000000..55177a4 --- /dev/null +++ b/test/esn/SConstruct @@ -0,0 +1,15 @@ +env = Environment( + CCFLAGS = ['-g', '-Wall', '-Werror', '--include=harness.h'], + LINKFLAGS = ['-g'], + CPPPATH = ['.', '../../src/include'], +) + +env.Append( + CCFLAGS = ['-fprofile-arcs', '-ftest-coverage'], + LINKFLAGS = ['-fprofile-arcs', '-ftest-coverage'], +) + +env.Program('test-esn', [ + 'harness.c', + '../../src/net/xfrm/xfrm_replay.c', +]) diff --git a/test/esn/harness.c b/test/esn/harness.c new file mode 100644 index 0000000..d026023 --- /dev/null +++ b/test/esn/harness.c @@ -0,0 +1,257 @@ +#include "harness.h" +#include + +static void print_bitmap(struct xfrm_state *x) +{ + unsigned k; + u32 bm = x->replay.bitmap; + + printk("bitmap: %u [", x->replay.seq - x->props.replay_window + 1); + bm <<= 32 - x->props.replay_window; + for (k = 0; k < x->props.replay_window; k++) { + if (k && !(k % 4)) + printk(" "); + printk("%c", (bm & (1 << 31)) ? '1' : '-'); + bm <<= 1; + } + printk("] %u\n", x->replay.seq); +} + +static int do_replay(struct xfrm_state *x, u64 seq64, unsigned should_fail) +{ + printk("\ntest: #%llu (%llu / %llu)\n", + seq64, + seq64 >> 32, + seq64 & 0xffffffff); + print_bitmap(x); + printk("w=%u bottom=%u top(replay.seq)=%u|%u\n", + x->props.replay_window, + x->replay.seq - x->props.replay_window + 1, + x->replay_ext.seq_hi, + x->replay.seq); + + u32 seq = htonl(seq64 & 0xffffffff); + if (xfrm_replay_check(x, seq)) { + printk("### replay check failed\n"); + if (!should_fail) + BUG(); + return -1; + } + + if (x->props.flags & XFRM_STATE_ESN) { + u32 seq_hi = xfrm_replay_seqhi(x, seq); + printk("seq_hi=%u\n", seq_hi); + if (seq_hi != (seq64 >> 32)) { + /* this is equivalent to the integrity check */ + printk("### seq_hi check failed (expected %llu)\n", seq64 >> 32); + if (!should_fail) + BUG(); + return -1; + } + } + + if (should_fail) { + printk("### replay check didn't fail -- and should have\n"); + BUG(); + } + + xfrm_replay_advance(x, seq); + return 0; +} + +static inline int test_replay_pass(struct xfrm_state *x, u64 seq64) +{ + return do_replay(x, seq64, 0); +} + +static inline int test_replay_fail(struct xfrm_state *x, u64 seq64) +{ + return do_replay(x, seq64, 1); +} + +static void init_state(struct xfrm_state *x) +{ + memset(x, 0, sizeof(struct xfrm_state)); + x->props.replay_window = 8; +} + +static void init_state_esn(struct xfrm_state *x) +{ + init_state(x); + x->props.flags |= XFRM_STATE_ESN; +} + +static void banner(const char *text) +{ + printk("\n\n================================================================\n"); + printk("===== %s\n\n", text); + +} + +static void sep(void) +{ + printk("\n\n-----\n\n"); +} + +static void test_0(void) +{ + struct xfrm_state st, *x = &st; + + banner("seq == 0"); + init_state_esn(x); + test_replay_fail(x, 0); + test_replay_pass(x, 1); + test_replay_fail(x, 0); + test_replay_pass(x, 128); + test_replay_fail(x, 0); + test_replay_pass(x, (1ULL << 32) - 20); + test_replay_fail(x, 0); + test_replay_pass(x, (1ULL << 32)); + test_replay_pass(x, (1ULL << 32) + 20); +} + +static void test_1(void) +{ + struct xfrm_state st, *x = &st; + unsigned k; + u64 seq64 = 1; + + banner("linear sequence, wrapping"); + init_state_esn(x); + + seq64 = 1; + for (k = 1; k < 5; k++) + test_replay_pass(x, seq64++); + sep(); + seq64 = 0xfffffff0; + for (k = 0; k < 16; k++) + test_replay_pass(x, seq64++); + sep(); + for (k = 0; k < 10; k++) + test_replay_pass(x, seq64++); +} + +static void test_2(void) +{ + struct xfrm_state st, *x = &st; + unsigned k; + u64 seq64 = 1; + + banner("short sequence with a few replays"); + init_state_esn(x); + + for (k = 0; k < 64; k++) + test_replay_pass(x, seq64++); + /* out-of-window */ + test_replay_fail(x, 1); + test_replay_fail(x, 2); + test_replay_fail(x, 3); + /* in-window */ + test_replay_fail(x, 60); + test_replay_fail(x, 63); + + test_replay_pass(x, seq64++); +} + +static void test_3(void) +{ + struct xfrm_state st, *x = &st; + + banner("swiss cheese"); + init_state_esn(x); + + test_replay_pass(x, 3); + test_replay_pass(x, 9); + test_replay_pass(x, 5); + test_replay_fail(x, 5); /* replayed */ + test_replay_pass(x, 16); + test_replay_fail(x, 4); /* out of window */ + test_replay_pass(x, 10); +} + +static void test_4(void) +{ + struct xfrm_state st, *x = &st; + u64 edge = (1ULL << 32); + + banner("swiss cheese with wrapping"); + init_state_esn(x); + + test_replay_pass(x, 1); + test_replay_pass(x, 128); + test_replay_pass(x, edge + 2); + test_replay_pass(x, edge - 2); + test_replay_pass(x, edge); + test_replay_pass(x, edge + 3); + test_replay_pass(x, edge + 1); + + test_replay_fail(x, edge + 1); + test_replay_fail(x, edge); + test_replay_fail(x, edge - 2); + test_replay_pass(x, edge - 1); +} + +static void test_5(void) +{ + struct xfrm_state st, *x = &st; + unsigned k; + u64 seq64 = 1; + + banner("sparse"); + init_state_esn(x); + + for (k = 1; k < 10; k++) { + seq64 += 2149536563U; /* random prime */ + test_replay_pass(x, seq64); + } +} + +static void test_plain_1(void) +{ + struct xfrm_state st, *x = &st; + unsigned k; + u64 seq64 = 1; + + banner("non-ESN in-sequence"); + init_state(x); + + for (k = 1; k < 10; k++) + test_replay_pass(x, seq64++); + for (k = 1; k < 3; k++) + test_replay_pass(x, seq64 += 13); + for (k = 1; k < 3; k++) + test_replay_pass(x, seq64 += 5); +} + +static void test_plain_2(void) +{ + struct xfrm_state st, *x = &st; + + banner("non-ESN replay check"); + init_state(x); + + test_replay_fail(x, 0); /* seq == 0 */ + test_replay_pass(x, 3); + test_replay_pass(x, 9); + test_replay_pass(x, 5); + test_replay_fail(x, 5); /* replayed */ + test_replay_pass(x, 16); + test_replay_fail(x, 4); /* out of window */ + test_replay_pass(x, 10); +} + +int main(int argc, char *argv[]) +{ + test_0(); + test_1(); + test_2(); + test_3(); + test_4(); + test_5(); + test_plain_1(); + test_plain_2(); + + sep(); + printk("all done.\n"); + return 0; +} diff --git a/test/esn/harness.h b/test/esn/harness.h new file mode 100644 index 0000000..1e4277b --- /dev/null +++ b/test/esn/harness.h @@ -0,0 +1,37 @@ +#ifndef _HARNESS_H +#define _HARNESS_H + +#include +#include +#include +#include +#include +#include + +#define printk printf +#define likely(x) x +#define unlikely(x) x +#define BUG() abort() +#define _NET_XFRM_H + +typedef u_int8_t u8; +typedef u_int32_t u32; +typedef u_int64_t u64; + +struct xfrm_state { + struct { + u8 flags; + u8 replay_window; + } props; + struct xfrm_replay_state replay; + struct xfrm_replay_state_ext replay_ext; + struct xfrm_stats stats; +}; + +#define XFRM_STATE_ESN 64 + +extern int xfrm_replay_check(struct xfrm_state *x, u32 seq); +extern u32 xfrm_replay_seqhi(struct xfrm_state *x, u32 seq); +extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq); + +#endif -- 1.5.4.3