[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20230120065142.78346-1-apoorvko@amazon.com>
Date: Thu, 19 Jan 2023 22:51:42 -0800
From: Apoorv Kothari <apoorvko@...zon.com>
To: <sd@...asysnail.net>
CC: <fkrenzel@...hat.com>, <netdev@...r.kernel.org>
Subject: [PATCH net-next 5/5] selftests: tls: add rekey tests
> Signed-off-by: Sabrina Dubroca <sd@...asysnail.net>
> ---
> tools/testing/selftests/net/tls.c | 258 ++++++++++++++++++++++++++++++
> 1 file changed, 258 insertions(+)
>
> diff --git a/tools/testing/selftests/net/tls.c b/tools/testing/selftests/net/tls.c
> index 5f3adb28fee1..97c20e2246e1 100644
> --- a/tools/testing/selftests/net/tls.c
> +++ b/tools/testing/selftests/net/tls.c
> @@ -1453,6 +1453,264 @@ TEST_F(tls, shutdown_reuse)
> EXPECT_EQ(errno, EISCONN);
> }
>
> +#define TLS_RECORD_TYPE_HANDSHAKE 0x16
> +/* key_update, length 1, update_not_requested */
> +static const char key_update_msg[] = "\x18\x00\x00\x01\x00";
> +static void tls_send_keyupdate(struct __test_metadata *_metadata, int fd)
> +{
> + size_t len = sizeof(key_update_msg);
> +
> + EXPECT_EQ(tls_send_cmsg(fd, TLS_RECORD_TYPE_HANDSHAKE,
> + (char *)key_update_msg, len, 0),
> + len);
> +}
> +
> +static void tls_recv_keyupdate(struct __test_metadata *_metadata, int fd, int flags)
> +{
> + char buf[100];
> +
> + EXPECT_EQ(tls_recv_cmsg(_metadata, fd, TLS_RECORD_TYPE_HANDSHAKE, buf, sizeof(buf), flags),
> + sizeof(key_update_msg));
> + EXPECT_EQ(memcmp(buf, key_update_msg, sizeof(key_update_msg)), 0);
> +}
> +
> +/* set the key to 0 then 1 for RX, immediately to 1 for TX */
> +TEST_F(tls_basic, rekey_rx)
> +{
> + struct tls_crypto_info_keys tls12_0, tls12_1;
nit: Did you mean tls13_0 and tls13_1? There are also a few others in this patch.
> + char const *test_str = "test_message";
> + int send_len = strlen(test_str) + 1;
> + char buf[20];
> + int ret;
> +
> + if (self->notls)
> + return;
> +
> + tls_crypto_info_init(TLS_1_3_VERSION, TLS_CIPHER_AES_GCM_128,
> + &tls12_0, 0);
> + tls_crypto_info_init(TLS_1_3_VERSION, TLS_CIPHER_AES_GCM_128,
> + &tls12_1, 1);
> +
> +
> + ret = setsockopt(self->fd, SOL_TLS, TLS_TX, &tls12_1, tls12_1.len);
> + ASSERT_EQ(ret, 0);
> +
> + ret = setsockopt(self->cfd, SOL_TLS, TLS_RX, &tls12_0, tls12_0.len);
> + ASSERT_EQ(ret, 0);
> +
> + ret = setsockopt(self->cfd, SOL_TLS, TLS_RX, &tls12_1, tls12_1.len);
> + EXPECT_EQ(ret, 0);
> +
> + EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
> + EXPECT_EQ(recv(self->cfd, buf, send_len, 0), send_len);
> + EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
> +}
> +
> +/* set the key to 0 then 1 for TX, immediately to 1 for RX */
> +TEST_F(tls_basic, rekey_tx)
> +{
> + struct tls_crypto_info_keys tls12_0, tls12_1;
> + char const *test_str = "test_message";
> + int send_len = strlen(test_str) + 1;
> + char buf[20];
> + int ret;
> +
> + if (self->notls)
> + return;
> +
> + tls_crypto_info_init(TLS_1_3_VERSION, TLS_CIPHER_AES_GCM_128,
> + &tls12_0, 0);
> + tls_crypto_info_init(TLS_1_3_VERSION, TLS_CIPHER_AES_GCM_128,
> + &tls12_1, 1);
> +
> +
> + ret = setsockopt(self->fd, SOL_TLS, TLS_TX, &tls12_0, tls12_0.len);
> + ASSERT_EQ(ret, 0);
> +
> + ret = setsockopt(self->cfd, SOL_TLS, TLS_RX, &tls12_1, tls12_1.len);
> + ASSERT_EQ(ret, 0);
> +
> + ret = setsockopt(self->fd, SOL_TLS, TLS_TX, &tls12_1, tls12_1.len);
> + EXPECT_EQ(ret, 0);
> +
> + EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
> + EXPECT_EQ(recv(self->cfd, buf, send_len, 0), send_len);
> + EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
> +}
> +
> +TEST_F(tls, rekey)
> +{
> + char const *test_str_1 = "test_message_before_rekey";
> + char const *test_str_2 = "test_message_after_rekey";
> + struct tls_crypto_info_keys tls12;
> + int send_len;
> + char buf[100];
> +
> + if (variant->tls_version != TLS_1_3_VERSION)
> + return;
> +
> + /* initial send/recv */
> + send_len = strlen(test_str_1) + 1;
> + EXPECT_EQ(send(self->fd, test_str_1, send_len, 0), send_len);
> + EXPECT_EQ(recv(self->cfd, buf, send_len, 0), send_len);
> + EXPECT_EQ(memcmp(buf, test_str_1, send_len), 0);
> +
> + /* update TX key */
> + tls_send_keyupdate(_metadata, self->fd);
> + tls_crypto_info_init(variant->tls_version, variant->cipher_type, &tls12, 1);
> + EXPECT_EQ(setsockopt(self->fd, SOL_TLS, TLS_TX, &tls12, tls12.len), 0);
> +
> + /* send after rekey */
> + send_len = strlen(test_str_2) + 1;
> + EXPECT_EQ(send(self->fd, test_str_2, send_len, 0), send_len);
> +
> + /* can't receive the KeyUpdate without a control message */
> + EXPECT_EQ(recv(self->cfd, buf, send_len, 0), -1);
> +
> + /* get KeyUpdate */
> + tls_recv_keyupdate(_metadata, self->cfd, 0);
> +
> + /* recv blocking -> -EKEYEXPIRED */
> + EXPECT_EQ(recv(self->cfd, buf, sizeof(buf), 0), -1);
> + EXPECT_EQ(errno, EKEYEXPIRED);
> +
> + /* recv non-blocking -> -EKEYEXPIRED */
> + EXPECT_EQ(recv(self->cfd, buf, sizeof(buf), MSG_DONTWAIT), -1);
> + EXPECT_EQ(errno, EKEYEXPIRED);
> +
> + /* update RX key */
> + EXPECT_EQ(setsockopt(self->cfd, SOL_TLS, TLS_RX, &tls12, tls12.len), 0);
> +
> + /* recv after rekey */
> + EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1);
> + EXPECT_EQ(memcmp(buf, test_str_2, send_len), 0);
> +}
> +
> +TEST_F(tls, rekey_peek)
> +{
> + char const *test_str_1 = "test_message_before_rekey";
> + struct tls_crypto_info_keys tls12;
> + int send_len;
> + char buf[100];
> +
> + if (variant->tls_version != TLS_1_3_VERSION)
> + return;
> +
> + send_len = strlen(test_str_1) + 1;
> + EXPECT_EQ(send(self->fd, test_str_1, send_len, 0), send_len);
> +
> + /* update TX key */
> + tls_send_keyupdate(_metadata, self->fd);
> + tls_crypto_info_init(variant->tls_version, variant->cipher_type, &tls12, 1);
> + EXPECT_EQ(setsockopt(self->fd, SOL_TLS, TLS_TX, &tls12, tls12.len), 0);
> +
> + EXPECT_EQ(recv(self->cfd, buf, sizeof(buf), MSG_PEEK), send_len);
> + EXPECT_EQ(memcmp(buf, test_str_1, send_len), 0);
> +
> + EXPECT_EQ(recv(self->cfd, buf, send_len, 0), send_len);
> + EXPECT_EQ(memcmp(buf, test_str_1, send_len), 0);
> +
> + /* can't receive the KeyUpdate without a control message */
> + EXPECT_EQ(recv(self->cfd, buf, send_len, MSG_PEEK), -1);
> +
> + /* peek KeyUpdate */
> + tls_recv_keyupdate(_metadata, self->cfd, MSG_PEEK);
> +
> + /* get KeyUpdate */
> + tls_recv_keyupdate(_metadata, self->cfd, 0);
> +
> + /* update RX key */
> + EXPECT_EQ(setsockopt(self->cfd, SOL_TLS, TLS_RX, &tls12, tls12.len), 0);
> +}
> +
> +TEST_F(tls, splice_rekey)
> +{
> + int send_len = TLS_PAYLOAD_MAX_LEN / 2;
> + char mem_send[TLS_PAYLOAD_MAX_LEN];
> + char mem_recv[TLS_PAYLOAD_MAX_LEN];
> + struct tls_crypto_info_keys tls12;
> + int p[2];
> +
> + if (variant->tls_version != TLS_1_3_VERSION)
> + return;
> +
> + memrnd(mem_send, sizeof(mem_send));
> +
> + ASSERT_GE(pipe(p), 0);
> + EXPECT_EQ(send(self->fd, mem_send, send_len, 0), send_len);
> +
> + /* update TX key */
> + tls_send_keyupdate(_metadata, self->fd);
> + tls_crypto_info_init(variant->tls_version, variant->cipher_type, &tls12, 1);
> + EXPECT_EQ(setsockopt(self->fd, SOL_TLS, TLS_TX, &tls12, tls12.len), 0);
> +
> + EXPECT_EQ(send(self->fd, mem_send, send_len, 0), send_len);
> +
> + EXPECT_EQ(splice(self->cfd, NULL, p[1], NULL, TLS_PAYLOAD_MAX_LEN, 0), send_len);
> + EXPECT_EQ(read(p[0], mem_recv, send_len), send_len);
> + EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
> +
> + /* can't splice the KeyUpdate */
> + EXPECT_EQ(splice(self->cfd, NULL, p[1], NULL, TLS_PAYLOAD_MAX_LEN, 0), -1);
> + EXPECT_EQ(errno, EINVAL);
> +
> + /* peek KeyUpdate */
> + tls_recv_keyupdate(_metadata, self->cfd, MSG_PEEK);
> +
> + /* get KeyUpdate */
> + tls_recv_keyupdate(_metadata, self->cfd, 0);
> +
> + /* can't splice before updating the key */
> + EXPECT_EQ(splice(self->cfd, NULL, p[1], NULL, TLS_PAYLOAD_MAX_LEN, 0), -1);
> + EXPECT_EQ(errno, EKEYEXPIRED);
> +
> + /* update RX key */
> + EXPECT_EQ(setsockopt(self->cfd, SOL_TLS, TLS_RX, &tls12, tls12.len), 0);
> +
> + EXPECT_EQ(splice(self->cfd, NULL, p[1], NULL, TLS_PAYLOAD_MAX_LEN, 0), send_len);
> + EXPECT_EQ(read(p[0], mem_recv, send_len), send_len);
> + EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
> +}
> +
> +TEST_F(tls, rekey_getsockopt)
> +{
> + struct tls_crypto_info_keys tls12;
> + struct tls_crypto_info_keys tls12_get;
> + socklen_t len;
> +
> + tls_crypto_info_init(variant->tls_version, variant->cipher_type, &tls12, 0);
> +
> + len = tls12.len;
> + EXPECT_EQ(getsockopt(self->fd, SOL_TLS, TLS_TX, &tls12_get, &len), 0);
> + EXPECT_EQ(len, tls12.len);
> + EXPECT_EQ(memcmp(&tls12_get, &tls12, tls12.len), 0);
> +
> + len = tls12.len;
> + EXPECT_EQ(getsockopt(self->cfd, SOL_TLS, TLS_RX, &tls12_get, &len), 0);
> + EXPECT_EQ(len, tls12.len);
> + EXPECT_EQ(memcmp(&tls12_get, &tls12, tls12.len), 0);
> +
> + if (variant->tls_version != TLS_1_3_VERSION)
> + return;
> +
> + tls_send_keyupdate(_metadata, self->fd);
> + tls_crypto_info_init(variant->tls_version, variant->cipher_type, &tls12, 1);
> + EXPECT_EQ(setsockopt(self->fd, SOL_TLS, TLS_TX, &tls12, tls12.len), 0);
> +
> + tls_recv_keyupdate(_metadata, self->cfd, 0);
> + EXPECT_EQ(setsockopt(self->cfd, SOL_TLS, TLS_RX, &tls12, tls12.len), 0);
> +
> + len = tls12.len;
> + EXPECT_EQ(getsockopt(self->fd, SOL_TLS, TLS_TX, &tls12_get, &len), 0);
> + EXPECT_EQ(len, tls12.len);
> + EXPECT_EQ(memcmp(&tls12_get, &tls12, tls12.len), 0);
> +
> + len = tls12.len;
> + EXPECT_EQ(getsockopt(self->cfd, SOL_TLS, TLS_RX, &tls12_get, &len), 0);
> + EXPECT_EQ(len, tls12.len);
> + EXPECT_EQ(memcmp(&tls12_get, &tls12, tls12.len), 0);
> +}
> +
> FIXTURE(tls_err)
> {
> int fd, cfd;
> --
> 2.38.1
Powered by blists - more mailing lists