Re: [PATCH net-next] selftests: tls: add selftests for TLS sockets

2018-07-16 Thread David Miller
From: Dave Watson 
Date: Thu, 12 Jul 2018 10:59:20 -0700

> Add selftests for tls socket.  Tests various iov and message options,
> poll blocking and nonblocking behavior, partial message sends / receives,
>  and control message data.  Tests should pass regardless of if TLS
> is enabled in the kernel or not, and print a warning message if not.
> 
> Signed-off-by: Dave Watson 

This is great, thanks Dave!

Applied to net-next.


[PATCH net-next] selftests: tls: add selftests for TLS sockets

2018-07-12 Thread Dave Watson
Add selftests for tls socket.  Tests various iov and message options,
poll blocking and nonblocking behavior, partial message sends / receives,
 and control message data.  Tests should pass regardless of if TLS
is enabled in the kernel or not, and print a warning message if not.

Signed-off-by: Dave Watson 
---
 tools/testing/selftests/net/Makefile |   2 +-
 tools/testing/selftests/net/tls.c| 692 +++
 2 files changed, 693 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/net/tls.c

diff --git a/tools/testing/selftests/net/Makefile 
b/tools/testing/selftests/net/Makefile
index 663e11e85727..9cca68e440a0 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -13,7 +13,7 @@ TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy
 TEST_GEN_FILES += tcp_mmap tcp_inq psock_snd
 TEST_GEN_FILES += udpgso udpgso_bench_tx udpgso_bench_rx
 TEST_GEN_PROGS = reuseport_bpf reuseport_bpf_cpu reuseport_bpf_numa
-TEST_GEN_PROGS += reuseport_dualstack reuseaddr_conflict
+TEST_GEN_PROGS += reuseport_dualstack reuseaddr_conflict tls
 
 include ../lib.mk
 
diff --git a/tools/testing/selftests/net/tls.c 
b/tools/testing/selftests/net/tls.c
new file mode 100644
index ..b3ebf2646e52
--- /dev/null
+++ b/tools/testing/selftests/net/tls.c
@@ -0,0 +1,692 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#define _GNU_SOURCE
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include "../kselftest_harness.h"
+
+#define TLS_PAYLOAD_MAX_LEN 16384
+#define SOL_TLS 282
+
+FIXTURE(tls)
+{
+   int fd, cfd;
+   bool notls;
+};
+
+FIXTURE_SETUP(tls)
+{
+   struct tls12_crypto_info_aes_gcm_128 tls12;
+   struct sockaddr_in addr;
+   socklen_t len;
+   int sfd, ret;
+
+   self->notls = false;
+   len = sizeof(addr);
+
+   memset(, 0, sizeof(tls12));
+   tls12.info.version = TLS_1_2_VERSION;
+   tls12.info.cipher_type = TLS_CIPHER_AES_GCM_128;
+
+   addr.sin_family = AF_INET;
+   addr.sin_addr.s_addr = htonl(INADDR_ANY);
+   addr.sin_port = 0;
+
+   self->fd = socket(AF_INET, SOCK_STREAM, 0);
+   sfd = socket(AF_INET, SOCK_STREAM, 0);
+
+   ret = bind(sfd, , sizeof(addr));
+   ASSERT_EQ(ret, 0);
+   ret = listen(sfd, 10);
+   ASSERT_EQ(ret, 0);
+
+   ret = getsockname(sfd, , );
+   ASSERT_EQ(ret, 0);
+
+   ret = connect(self->fd, , sizeof(addr));
+   ASSERT_EQ(ret, 0);
+
+   ret = setsockopt(self->fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
+   if (ret != 0) {
+   self->notls = true;
+   printf("Failure setting TCP_ULP, testing without tls\n");
+   }
+
+   if (!self->notls) {
+   ret = setsockopt(self->fd, SOL_TLS, TLS_TX, ,
+sizeof(tls12));
+   ASSERT_EQ(ret, 0);
+   }
+
+   self->cfd = accept(sfd, , );
+   ASSERT_GE(self->cfd, 0);
+
+   if (!self->notls) {
+   ret = setsockopt(self->cfd, IPPROTO_TCP, TCP_ULP, "tls",
+sizeof("tls"));
+   ASSERT_EQ(ret, 0);
+
+   ret = setsockopt(self->cfd, SOL_TLS, TLS_RX, ,
+sizeof(tls12));
+   ASSERT_EQ(ret, 0);
+   }
+
+   close(sfd);
+}
+
+FIXTURE_TEARDOWN(tls)
+{
+   close(self->fd);
+   close(self->cfd);
+}
+
+TEST_F(tls, sendfile)
+{
+   int filefd = open("/proc/self/exe", O_RDONLY);
+   struct stat st;
+
+   EXPECT_GE(filefd, 0);
+   fstat(filefd, );
+   EXPECT_GE(sendfile(self->fd, filefd, 0, st.st_size), 0);
+}
+
+TEST_F(tls, send_then_sendfile)
+{
+   int filefd = open("/proc/self/exe", O_RDONLY);
+   char const *test_str = "test_send";
+   int to_send = strlen(test_str) + 1;
+   char recv_buf[10];
+   struct stat st;
+   char *buf;
+
+   EXPECT_GE(filefd, 0);
+   fstat(filefd, );
+   buf = (char *)malloc(st.st_size);
+
+   EXPECT_EQ(send(self->fd, test_str, to_send, 0), to_send);
+   EXPECT_EQ(recv(self->cfd, recv_buf, to_send, 0), to_send);
+   EXPECT_EQ(memcmp(test_str, recv_buf, to_send), 0);
+
+   EXPECT_GE(sendfile(self->fd, filefd, 0, st.st_size), 0);
+   EXPECT_EQ(recv(self->cfd, buf, st.st_size, 0), st.st_size);
+}
+
+TEST_F(tls, recv_max)
+{
+   unsigned int send_len = TLS_PAYLOAD_MAX_LEN;
+   char recv_mem[TLS_PAYLOAD_MAX_LEN];
+   char buf[TLS_PAYLOAD_MAX_LEN];
+
+   EXPECT_GE(send(self->fd, buf, send_len, 0), 0);
+   EXPECT_NE(recv(self->cfd, recv_mem, send_len, 0), -1);
+   EXPECT_EQ(memcmp(buf, recv_mem, send_len), 0);
+}
+
+TEST_F(tls, recv_small)
+{
+   char const *test_str = "test_read";
+   int send_len = 10;
+   char buf[10];
+
+   send_len = strlen(test_str) + 1;
+   EXPECT_EQ(send(self->fd, test_str,