From: Dmitry Safonov <dima@arista.com>
To: linux-kernel@vger.kernel.org, David Ahern <dsahern@kernel.org>,
Eric Dumazet <edumazet@google.com>
Cc: Dmitry Safonov <dima@arista.com>,
Andy Lutomirski <luto@amacapital.net>,
Ard Biesheuvel <ardb@kernel.org>,
Bob Gilligan <gilligan@arista.com>,
Dan Carpenter <dan.carpenter@oracle.com>,
"David S. Miller" <davem@davemloft.net>,
Dmitry Safonov <0x7f454c46@gmail.com>,
Eric Biggers <ebiggers@kernel.org>,
"Eric W. Biederman" <ebiederm@xmission.com>,
Francesco Ruggeri <fruggeri@arista.com>,
Herbert Xu <herbert@gondor.apana.org.au>,
Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>,
Ivan Delalande <colona@arista.com>,
Jakub Kicinski <kuba@kernel.org>,
Leonard Crestez <cdleonard@gmail.com>,
Paolo Abeni <pabeni@redhat.com>,
Salam Noureddine <noureddine@arista.com>,
Shuah Khan <shuah@kernel.org>,
netdev@vger.kernel.org, linux-crypto@vger.kernel.org
Subject: [PATCH v2 34/35] selftests/nettest: Add TCP-AO support
Date: Fri, 23 Sep 2022 21:13:18 +0100 [thread overview]
Message-ID: <20220923201319.493208-35-dima@arista.com> (raw)
In-Reply-To: <20220923201319.493208-1-dima@arista.com>
Roughly, the same as TCP-MD5 support.
Signed-off-by: Dmitry Safonov <dima@arista.com>
---
tools/testing/selftests/net/nettest.c | 179 +++++++++++++++++++++++---
1 file changed, 160 insertions(+), 19 deletions(-)
diff --git a/tools/testing/selftests/net/nettest.c b/tools/testing/selftests/net/nettest.c
index 3a887ef783cd..e9d6c15c014a 100644
--- a/tools/testing/selftests/net/nettest.c
+++ b/tools/testing/selftests/net/nettest.c
@@ -77,7 +77,9 @@ struct sock_args {
has_expected_laddr:1,
has_expected_raddr:1,
bind_test_only:1,
- use_md5:1;
+ use_md5:1,
+ use_tcpao:1,
+ tcp_ao_excopts:1;
unsigned short port;
@@ -96,7 +98,7 @@ struct sock_args {
const char *serverns;
const char *password;
- /* prefix for MD5 password */
+ /* prefix for MD5/TCP-AO password */
const char *auth_prefix_str;
union {
struct sockaddr_in v4;
@@ -105,6 +107,8 @@ struct sock_args {
unsigned int prefix_len;
/* 0: default, -1: force off, +1: force on */
int bind_key_ifindex;
+ unsigned tcp_ao_sndid, tcp_ao_rcvid, tcp_ao_maclen;
+ char *tcp_ao_algo;
/* expected addresses and device index for connection */
const char *expected_dev;
@@ -297,7 +301,67 @@ static int tcp_md5sig(int sd, void *addr, socklen_t alen, struct sock_args *args
return rc;
}
-static int tcp_md5_remote(int sd, struct sock_args *args)
+static int tcp_ao(int sd, void *addr, socklen_t alen, struct sock_args *args)
+{
+ int keylen = strlen(args->password);
+ struct tcp_ao ao = {};
+ int opt = TCP_AO;
+ int rc;
+
+ if (keylen > TCP_AO_MAXKEYLEN) {
+ log_error("key length is too big");
+ return -1;
+ }
+ ao.tcpa_keylen = keylen;
+ memcpy(ao.tcpa_key, args->password, keylen);
+ if (args->tcp_ao_algo)
+ strcpy(ao.tcpa_alg_name, args->tcp_ao_algo);
+ else
+ strcpy(ao.tcpa_alg_name, "cmac(aes128)");
+ if (args->tcp_ao_maclen)
+ ao.tcpa_maclen = args->tcp_ao_maclen;
+
+ ao.tcpa_sndid = args->tcp_ao_sndid;
+ ao.tcpa_rcvid = args->tcp_ao_rcvid;
+ if (args->tcp_ao_excopts)
+ ao.tcpa_keyflags |= TCP_AO_KEYF_EXCLUDE_OPT;
+
+ if (args->prefix_len) {
+ ao.tcpa_prefix = args->prefix_len;
+ } else {
+ switch (args->version) {
+ case AF_INET:
+ ao.tcpa_prefix = 32;
+ break;
+ case AF_INET6:
+ ao.tcpa_prefix = 128;
+ break;
+ default:
+ log_error("unknown address family\n");
+ exit(1);
+ }
+ }
+ memcpy(&ao.tcpa_addr, addr, alen);
+
+ /* FIXME: Remove once matching by port is supported */
+ if (args->version == AF_INET) {
+ struct sockaddr_in *sin = (void *)&ao.tcpa_addr;
+
+ sin->sin_port = htons(0);
+ } else if (args->version == AF_INET6) {
+ struct sockaddr_in6 *sin6 = (void *)&ao.tcpa_addr;
+
+ sin6->sin6_port = htons(0);
+ }
+
+ rc = setsockopt(sd, IPPROTO_TCP, opt, &ao, sizeof(ao));
+ if (rc < 0)
+ log_err_errno("setsockopt(TCP_AO)");
+
+ return rc;
+}
+
+static int tcp_auth_remote(int sd, struct sock_args *args)
{
struct sockaddr_in sin = {
.sin_family = AF_INET,
@@ -326,7 +390,10 @@ static int tcp_md5_remote(int sd, struct sock_args *args)
exit(1);
}
- if (tcp_md5sig(sd, addr, alen, args))
+ if (args->use_md5 && tcp_md5sig(sd, addr, alen, args))
+ return -1;
+
+ if (args->use_tcpao && tcp_ao(sd, addr, alen, args))
return -1;
return 0;
@@ -1538,10 +1605,8 @@ static int do_server(struct sock_args *args, int ipc_fd)
return rc;
}
- if (args->use_md5 && tcp_md5_remote(lsd, args)) {
- close(lsd);
- goto err_exit;
- }
+ if (tcp_auth_remote(lsd, args))
+ goto err_close;
ipc_write(ipc_fd, 1);
while (1) {
@@ -1590,6 +1655,8 @@ static int do_server(struct sock_args *args, int ipc_fd)
close(lsd);
return rc;
+err_close:
+ close(lsd);
err_exit:
ipc_write(ipc_fd, 0);
return 1;
@@ -1665,6 +1732,9 @@ static int connectsock(void *addr, socklen_t alen, struct sock_args *args)
if (args->use_md5 && tcp_md5sig(sd, addr, alen, args))
goto err;
+ if (args->use_tcpao && tcp_ao(sd, addr, alen, args))
+ goto err;
+
if (args->bind_test_only)
goto out;
@@ -1791,6 +1861,44 @@ static char *random_msg(int len)
return m;
}
+static void strip_newlines(char *str)
+{
+ size_t i = strlen(str);
+
+ for (; i > 0; i--) {
+ if (str[i - 1] != '\n')
+ return;
+ str[i - 1] = '\0';
+ }
+}
+
+static int set_tcp_ao_param(struct sock_args *args, const char *opt)
+{
+ char *end, *sep = strstr(opt, ":");
+ unsigned long tmp;
+
+ errno = 0;
+ if (sep == NULL)
+ goto err_fail;
+
+ tmp = strtoul(opt, &end, 0);
+ if (errno || tmp > 255 || end != sep)
+ goto err_fail;
+ args->tcp_ao_sndid = (unsigned) tmp;
+
+ tmp = strtoul(++sep, &end, 0);
+ if (errno || tmp > 255 || (*end != '\n' && *end != '\0'))
+ goto err_fail;
+ args->tcp_ao_rcvid = (unsigned) tmp;
+
+ return 0;
+
+err_fail:
+ fprintf(stderr, "TCP-AO argument format is sndid:rcvid where ids in [0,255]\n"
+ "Example: -T 100:200\n");
+ return -1;
+}
+
static int ipc_child(int fd, struct sock_args *args)
{
char *outbuf, *errbuf;
@@ -1852,13 +1960,19 @@ static int ipc_parent(int cpid, int fd, struct sock_args *args)
return client_status;
}
-#define GETOPT_STR "sr:l:c:p:t:g:P:DRn:MX:m:d:I:BN:O:SCi6xL:0:1:2:3:Fbqf"
-#define OPT_FORCE_BIND_KEY_IFINDEX 1001
-#define OPT_NO_BIND_KEY_IFINDEX 1002
+#define GETOPT_STR "sr:l:c:p:t:g:P:DRn:MT:X:m:d:I:BN:O:SCi6xL:0:1:2:3:Fbqf"
+#define OPT_FORCE_BIND_KEY_IFINDEX 1001
+#define OPT_NO_BIND_KEY_IFINDEX 1002
+#define OPT_TCPAO_ALGO 1003
+#define OPT_TCPAO_MACLEN 1004
+#define OPT_TCPAO_EXCOPTS 1005
static struct option long_opts[] = {
- {"force-bind-key-ifindex", 0, 0, OPT_FORCE_BIND_KEY_IFINDEX},
- {"no-bind-key-ifindex", 0, 0, OPT_NO_BIND_KEY_IFINDEX},
+ {"force-bind-key-ifindex", 0, 0, OPT_FORCE_BIND_KEY_IFINDEX},
+ {"no-bind-key-ifindex", 0, 0, OPT_NO_BIND_KEY_IFINDEX},
+ {"tcpao_algo", 1, 0, OPT_TCPAO_ALGO },
+ {"tcpao_maclen", 1, 0, OPT_TCPAO_MACLEN },
+ {"tcpao_excopts", 0, 0, OPT_TCPAO_EXCOPTS },
{0, 0, 0, 0}
};
@@ -1896,8 +2010,12 @@ static void print_usage(char *prog)
" -n num number of times to send message\n"
"\n"
" -M use MD5 sum protection\n"
- " -X password MD5 password\n"
- " -m prefix/len prefix and length to use for MD5 key\n"
+ " -T snd:rcvid use TCP authopt (RFC5925) with snd/rcv ids\n"
+ " --tcpao_algo=algo TCP-AO hashing algorithm [valid with -T]\n"
+ " --tcpao_maclen=maclen TCP-AO MAC length [valid with -T]\n"
+ " --tcpao_excopts Exclude TCP options [valid with -T]\n"
+ " -X password MD5/TCP-AO password\n"
+ " -m prefix/len prefix and length to use for MD5/TCP-AO key\n"
" --no-bind-key-ifindex: Force TCP_MD5SIG_FLAG_IFINDEX off\n"
" --force-bind-key-ifindex: Force TCP_MD5SIG_FLAG_IFINDEX on\n"
" (default: only if -I is passed)\n"
@@ -2016,6 +2134,29 @@ int main(int argc, char *argv[])
case OPT_NO_BIND_KEY_IFINDEX:
args.bind_key_ifindex = -1;
break;
+ case OPT_TCPAO_ALGO:
+ args.tcp_ao_algo = strdup(optarg);
+ strip_newlines(args.tcp_ao_algo);
+ if (strlen(args.tcp_ao_algo) == 0) {
+ fprintf(stderr, "Invalid argument --tcpao_algo=%s\n", optarg);
+ return 1;
+ }
+ break;
+ case OPT_TCPAO_MACLEN:
+ if (str_to_uint(optarg, 1, 255, &tmp) != 0) {
+ fprintf(stderr, "Invalid --tcpao_maclen=%s\n", optarg);
+ return 1;
+ }
+ args.tcp_ao_maclen = tmp;
+ break;
+ case OPT_TCPAO_EXCOPTS:
+ args.tcp_ao_excopts = 1;
+ break;
+ case 'T':
+ args.use_tcpao = 1;
+ if (set_tcp_ao_param(&args, optarg))
+ return 1;
+ break;
case 'X':
args.password = optarg;
break;
@@ -2078,15 +2219,15 @@ int main(int argc, char *argv[])
}
}
- if (args.password && (!args.use_md5 ||
+ if (args.password && ((!args.use_md5 && !args.use_tcpao) ||
(!args.has_remote_ip && !args.auth_prefix_str) ||
args.type != SOCK_STREAM)) {
- log_error("MD5 passwords apply to TCP only and require a remote ip for the password\n");
+ log_error("TCP-MD5/TCP-AO passwords apply to TCP only and require a remote ip for the password\n");
return 1;
}
- if ((args.auth_prefix_str || args.use_md5) && !args.password) {
- log_error("Prefix range for MD5 protection specified without a password\n");
+ if ((args.auth_prefix_str || args.use_md5 || args.use_tcpao) && !args.password) {
+ log_error("Prefix range for TCP-MD5/TCP-AO protection specified without a password\n");
return 1;
}
--
2.37.2
next prev parent reply other threads:[~2022-09-23 20:19 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-23 20:12 [PATCH v2 00/35] net/tcp: Add TCP-AO support Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 01/35] crypto: Introduce crypto_pool Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 02/35] crypto_pool: Add crypto_pool_reserve_scratch() Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 03/35] net/tcp: Separate tcp_md5sig_info allocation into tcp_md5sig_info_add() Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 04/35] net/tcp: Disable TCP-MD5 static key on tcp_md5sig_info destruction Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 05/35] net/tcp: Use crypto_pool for TCP-MD5 Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 06/35] net/ipv6: sr: Switch to using crypto_pool Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 07/35] tcp: Add TCP-AO config and structures Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 08/35] net/tcp: Introduce TCP_AO setsockopt()s Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 09/35] net/tcp: Prevent TCP-MD5 with TCP-AO being set Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 10/35] net/tcp: Calculate TCP-AO traffic keys Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 11/35] net/tcp: Add TCP-AO sign to outgoing packets Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 12/35] net/tcp: Add tcp_parse_auth_options() Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 13/35] net/tcp: Add AO sign to RST packets Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 14/35] net/tcp: Add TCP-AO sign to twsk Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 15/35] net/tcp: Wire TCP-AO to request sockets Dmitry Safonov
2022-09-24 5:23 ` kernel test robot
2022-09-23 20:13 ` [PATCH v2 16/35] net/tcp: Sign SYN-ACK segments with TCP-AO Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 17/35] net/tcp: Verify inbound TCP-AO signed segments Dmitry Safonov
2022-09-24 5:43 ` kernel test robot
2022-09-23 20:13 ` [PATCH v2 18/35] net/tcp: Add TCP-AO segments counters Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 19/35] net/tcp: Add TCP-AO SNE support Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 20/35] net/tcp: Add tcp_hash_fail() ratelimited logs Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 21/35] net/tcp: Ignore specific ICMPs for TCP-AO connections Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 22/35] net/tcp: Add option for TCP-AO to (not) hash header Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 23/35] net/tcp: Add getsockopt(TCP_AO_GET) Dmitry Safonov
2022-09-24 6:44 ` kernel test robot
2022-09-23 20:13 ` [PATCH v2 24/35] net/tcp: Allow asynchronous delete for TCP-AO keys (MKTs) Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 25/35] selftests/net: Add TCP-AO library Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 26/35] selftests/net: Verify that TCP-AO complies with ignoring ICMPs Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 27/35] selftest/net: Add TCP-AO ICMPs accept test Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 28/35] selftest/tcp-ao: Add a test for MKT matching Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 29/35] selftest/tcp-ao: Add test for TCP-AO add setsockopt() command Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 30/35] selftests/tcp-ao: Add TCP-AO + TCP-MD5 + no sign listen socket tests Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 31/35] selftests/aolib: Add test/benchmark for removing MKTs Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 32/35] selftests/nettest: Remove client_pw Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 33/35] selftest/nettest: Rename md5_prefix* => auth_prefix* Dmitry Safonov
2022-09-23 20:13 ` Dmitry Safonov [this message]
2022-09-23 20:13 ` [PATCH v2 35/35] selftests/fcnal-test.sh: Add TCP-AO tests Dmitry Safonov
2022-09-23 21:25 ` [PATCH v2 00/35] net/tcp: Add TCP-AO support Dmitry Safonov
2022-09-27 1:57 ` David Ahern
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220923201319.493208-35-dima@arista.com \
--to=dima@arista.com \
--cc=0x7f454c46@gmail.com \
--cc=ardb@kernel.org \
--cc=cdleonard@gmail.com \
--cc=colona@arista.com \
--cc=dan.carpenter@oracle.com \
--cc=davem@davemloft.net \
--cc=dsahern@kernel.org \
--cc=ebiederm@xmission.com \
--cc=ebiggers@kernel.org \
--cc=edumazet@google.com \
--cc=fruggeri@arista.com \
--cc=gilligan@arista.com \
--cc=herbert@gondor.apana.org.au \
--cc=kuba@kernel.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@amacapital.net \
--cc=netdev@vger.kernel.org \
--cc=noureddine@arista.com \
--cc=pabeni@redhat.com \
--cc=shuah@kernel.org \
--cc=yoshfuji@linux-ipv6.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).