From nobody Thu Apr 9 12:06:20 2026 Received: from mail-pg1-f175.google.com (mail-pg1-f175.google.com [209.85.215.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B3E1734CFB8 for ; Mon, 9 Mar 2026 05:54:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773035683; cv=none; b=lhfpL/OXvZOfFqAxT/zWc9NaFFEzFpOR6ZUWDLQVg4bjHVnGuLk+99wX+K0DhRxq4w3cUPyupJ1hYcd6P6fbv7qeVQSxn/DdGd3yg/+vzASHK1MRu2mCO1+xd+PqXETEmjuKqfWCc7fSsYWKjNqyXwF2q1rgMjwic/G/gNholJ8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773035683; c=relaxed/simple; bh=naXvgUL1vrrylA++ctQr+L9oQ71V0LFb27f4Yj4ef0M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Hw2IWeHoFZv9wvKHrh7Zkmc+ee6ioO74ky7rLUqwPuAI6xHIfc64UJoTOJJz344EzZA2q8/aqohi/0L/AIudIL5dDmpg5FvJzwI2hhJHr+kKI+3zclZ9kVDfFR19vG1DFunT7KYkvSkHZ1mTzjcC867d5jng1vQKqacEPJCLi84= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=XHjUVd+v; arc=none smtp.client-ip=209.85.215.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="XHjUVd+v" Received: by mail-pg1-f175.google.com with SMTP id 41be03b00d2f7-c2af7d09533so7159756a12.1 for ; Sun, 08 Mar 2026 22:54:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773035680; x=1773640480; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=AZOR83ZELRZ96AOmva1kehfsvl1uJwm5zQkZMO8Il2Y=; b=XHjUVd+vX7DcB+Fj7synsk8LCV3UWf+1e66c906/v23ZdJ/zJStor8Bbf9TTQ7aEDz iiXNwAYiGpKi+6UTqVRpQL8VUgAUs/qAfgBGWhPOcmbyMVXux9oWwYxGgKnyTmOSFRwl u/+xnYaTuFgcxCbEYuxd9hZZrXCCm3dqsRr+w967bOxDrE5toqCnNUH4Wfh3td8Ss4U8 K+CHHDwKrSDbKbxIpn0HJUhlL4BlTuIUJiAwjMX3aESfrpLsgT2Itc8Wxzdxf99ZaqVa 1kGLJ9cNWgE6Aefdn9BU1KmRboXWQjjkWJbk8zCoEKSGtE9xxKOvk5k2wa/2Dbw/rfXg 2SBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773035680; x=1773640480; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=AZOR83ZELRZ96AOmva1kehfsvl1uJwm5zQkZMO8Il2Y=; b=NZ5Hd65w6rMFKQTcz3xjU+qSw9oZI1qDyeB4Hq4/2Qco3TR3n7D238DEZq7CliCL5C 8EgPMQRTY8U74a/rXg6e3AF8DyhA9HWXHrg8vblc86/p88hhrCS1PAEx11k5S1QpFp6u A7Z2rjVw5ZYcuC3UsZqJ5nJ0E7qM+PgXahCsV4f6+FCpZMq6p01Mp3315bFM26i3lV+R 60j/Mhx3z9ih2QXYs+xX+CuHeCeObzO/VNeB5xnz9sdRD7tMqB623l8ZzbXIb62aorpF XkEy4bmhPG6H1HNSUVg0gRkUg1e2uksUL055G4d5IMfnFgepbSjyv8mCFVh1s2Uyqi4F gnqQ== X-Forwarded-Encrypted: i=1; AJvYcCX/2sD1nRBX1IiPLbj3fX+l18WzYxEzGZA69uiA6rCnT469YqzDJDycfCQqkKHGBBhn1dHYNSZL//3V/4U=@vger.kernel.org X-Gm-Message-State: AOJu0YzOj6Xg/+1KsnfpkNUom1NeFtGVa4JIMOa/KZCQTJuQ3dCD9Zc7 Bwvp7+VsdXR/5iaruuQfTh6yj4jk4Cyh+gUexRSCUD6vEsoq5XHljs7g X-Gm-Gg: ATEYQzwP4N+P8OQ2bgaqoxQwDicIxzPcl0D3Xb5/Mlc5+KPABfxqYdZryOyDgiRnivs tqH98gIlNCufPIBVUOV5ooqcZsBN+OZR8c4esQvRFlpb6gmwGpK+0jwvGViewjeHC5hXIcHAzyi NL6tUIAkMEXqE61Y2AjiCiqWuVYhjPkrddZtA50xIhx8AwuqdmCq3RjvMRMuYmYH6lcwjKz+ont +HlU/8lvOVSQ5gIPWxTI94ZRIj/5JKpQLszCAj8VsxZTTXNnqrv0fNCv19CpZAxTNWun1OZVtrp pgyWGoHpvWu4Q6hGQpawTCxQZELc7X36FPM5A4qS+vD+K1woEt69ERV1foso1p7p1OJRu40T3Iv RGepDHP4py1jY1aAPgKVdeconDrNpXv5Kqkuxr0U3V0Kg97Osj71CAkD82zUH+4AWRW3XWtnKbl VV1tNZw4qBYoOuMn16GdAtivD/7UV4xYW8J2/N7gOAQ6POqLfIFGlF69dE0Pkx2PJqG3WNlsY= X-Received: by 2002:a05:6a20:a10e:b0:398:7853:c495 with SMTP id adf61e73a8af0-3987853c6d0mr5367983637.3.1773035679994; Sun, 08 Mar 2026 22:54:39 -0700 (PDT) Received: from zenbook ([159.196.5.243]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-c739e170923sm7933716a12.17.2026.03.08.22.54.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Mar 2026 22:54:39 -0700 (PDT) From: Wilfred Mallawa To: John Fastabend , Jakub Kicinski , Sabrina Dubroca , "David S . Miller" , Eric Dumazet , Paolo Abeni , Simon Horman , Jonathan Corbet , Shuah Khan Cc: netdev@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Alistair Francis , Damien Le'Moal , Wilfred Mallawa Subject: [RFC net-next 1/3] net/tls_sw: support randomized zero padding Date: Mon, 9 Mar 2026 15:48:36 +1000 Message-ID: <20260309054837.2299732-3-wilfred.opensource@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309054837.2299732-2-wilfred.opensource@gmail.com> References: <20260309054837.2299732-2-wilfred.opensource@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Wilfred Mallawa Currently, for TLS 1.3, ktls does not support record zero padding [1]. Record zero padding is used to allow the sender to hide the size of the traffic patterns from an observer. TLS is susceptible to a variety of traff= ic analysis attacks based on observing the length and timing of encrypted packets [2]. Upcoming Western Digital NVMe-TCP hardware controllers implement TLS 1.3. Which from a security perspective, can benefit from havi= ng record zero padding enabled to mitigate against traffic analysis attacks [2= ]. Thus, for TX, add support to appending a randomized number of zero padding bytes to end-of-record (EOR) records that are not full. The number of zero padding bytes to append is determined by the remaining record room and the user specified upper bound (minimum of the two). That is rand([0, min(record_room, upper_bound)]). For TLS 1.3, zero padding is added after the content type byte, as such, if the record in context meets the above conditions for zero padding, attach a zero padding buffer to the content type byte before a record is encrypted. The padding buffer is freed when the record is freed. By default, record zero padding is disabled, and userspace may enable it by using the setsockopt TLS_TX_RANDOM_PAD option. [1] https://datatracker.ietf.org/doc/html/rfc8446#section-5.4l [2] https://datatracker.ietf.org/doc/html/rfc8446#appendix-E.3 Signed-off-by: Wilfred Mallawa --- include/net/tls.h | 1 + net/tls/tls.h | 6 ++++- net/tls/tls_main.c | 2 ++ net/tls/tls_sw.c | 58 ++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 56 insertions(+), 11 deletions(-) diff --git a/include/net/tls.h b/include/net/tls.h index ebd2550280ae..1feef72cc339 100644 --- a/include/net/tls.h +++ b/include/net/tls.h @@ -229,6 +229,7 @@ struct tls_context { u8 zerocopy_sendfile:1; u8 rx_no_pad:1; u16 tx_max_payload_len; + u16 tx_record_zero_pad; =20 int (*push_pending_record)(struct sock *sk, int flags); void (*sk_write_space)(struct sock *sk); diff --git a/net/tls/tls.h b/net/tls/tls.h index e8f81a006520..3a86eb145332 100644 --- a/net/tls/tls.h +++ b/net/tls/tls.h @@ -121,8 +121,12 @@ struct tls_rec { /* AAD | msg_encrypted.sg.data (data contains overhead for hdr & iv & tag= ) */ struct scatterlist sg_aead_out[2]; =20 + /* TLS 1.3 record zero padding */ + char *zero_padding; + u16 zero_padding_len; + char content_type; - struct scatterlist sg_content_type; + struct scatterlist sg_content_trail[2]; =20 struct sock *sk; =20 diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c index fd39acf41a61..b0702effbc26 100644 --- a/net/tls/tls_main.c +++ b/net/tls/tls_main.c @@ -1076,6 +1076,8 @@ static int tls_init(struct sock *sk) ctx->tx_conf =3D TLS_BASE; ctx->rx_conf =3D TLS_BASE; ctx->tx_max_payload_len =3D TLS_MAX_PAYLOAD_SIZE; + /* TX record zero padding is disabled by default */ + ctx->tx_record_zero_pad =3D 0; update_sk_prot(sk, ctx); out: write_unlock_bh(&sk->sk_callback_lock); diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index a656ce235758..84b167607e1f 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c @@ -389,6 +389,7 @@ static void tls_free_rec(struct sock *sk, struct tls_re= c *rec) { sk_msg_free(sk, &rec->msg_encrypted); sk_msg_free(sk, &rec->msg_plaintext); + kfree(rec->zero_padding); kfree(rec); } =20 @@ -430,6 +431,7 @@ int tls_tx_records(struct sock *sk, int flags) */ list_del(&rec->list); sk_msg_free(sk, &rec->msg_plaintext); + kfree(rec->zero_padding); kfree(rec); } =20 @@ -450,6 +452,7 @@ int tls_tx_records(struct sock *sk, int flags) =20 list_del(&rec->list); sk_msg_free(sk, &rec->msg_plaintext); + kfree(rec->zero_padding); kfree(rec); } else { break; @@ -779,12 +782,29 @@ static int tls_push_record(struct sock *sk, int flags, sk_msg_iter_var_prev(i); =20 rec->content_type =3D record_type; + if (prot->version =3D=3D TLS_1_3_VERSION) { - /* Add content type to end of message. No padding added */ - sg_set_buf(&rec->sg_content_type, &rec->content_type, 1); - sg_mark_end(&rec->sg_content_type); + /* + * Add content type to end of message with zero padding + * if available. + */ + sg_init_table(rec->sg_content_trail, 2); + sg_set_buf(&rec->sg_content_trail[0], &rec->content_type, 1); + if (rec->zero_padding_len) { + rec->zero_padding =3D kzalloc(rec->zero_padding_len, + sk->sk_allocation); + if (!rec->zero_padding) + return -ENOMEM; + + sg_set_buf(&rec->sg_content_trail[1], + rec->zero_padding, rec->zero_padding_len); + sg_mark_end(&rec->sg_content_trail[1]); + } else { + sg_mark_end(&rec->sg_content_trail[0]); + } + sg_chain(msg_pl->sg.data, msg_pl->sg.end + 1, - &rec->sg_content_type); + rec->sg_content_trail); } else { sg_mark_end(sk_msg_elem(msg_pl, i)); } @@ -805,19 +825,21 @@ static int tls_push_record(struct sock *sk, int flags, i =3D msg_en->sg.start; sg_chain(rec->sg_aead_out, 2, &msg_en->sg.data[i]); =20 - tls_make_aad(rec->aad_space, msg_pl->sg.size + prot->tail_size, - tls_ctx->tx.rec_seq, record_type, prot); + tls_make_aad(rec->aad_space, msg_pl->sg.size + prot->tail_size + + rec->zero_padding_len, tls_ctx->tx.rec_seq, + record_type, prot); =20 tls_fill_prepend(tls_ctx, page_address(sg_page(&msg_en->sg.data[i])) + msg_en->sg.data[i].offset, - msg_pl->sg.size + prot->tail_size, - record_type); + msg_pl->sg.size + prot->tail_size + + rec->zero_padding_len, record_type); =20 tls_ctx->pending_open_record_frags =3D false; =20 rc =3D tls_do_encryption(sk, tls_ctx, ctx, req, - msg_pl->sg.size + prot->tail_size, i); + msg_pl->sg.size + prot->tail_size + + rec->zero_padding_len, i); if (rc < 0) { if (rc !=3D -EINPROGRESS) { tls_err_abort(sk, -EBADMSG); @@ -1033,6 +1055,8 @@ static int tls_sw_sendmsg_locked(struct sock *sk, str= uct msghdr *msg, unsigned char record_type =3D TLS_RECORD_TYPE_DATA; bool is_kvec =3D iov_iter_is_kvec(&msg->msg_iter); bool eor =3D !(msg->msg_flags & MSG_MORE); + bool tls_13 =3D (prot->version =3D=3D TLS_1_3_VERSION); + bool rec_zero_pad =3D eor && tls_13 && tls_ctx->tx_record_zero_pad; size_t try_to_copy; ssize_t copied =3D 0; struct sk_msg *msg_pl, *msg_en; @@ -1043,6 +1067,7 @@ static int tls_sw_sendmsg_locked(struct sock *sk, str= uct msghdr *msg, int record_room; int num_zc =3D 0; int orig_size; + int max_zero_pad_len, zero_pad_len =3D 0; int ret =3D 0; =20 if (!eor && (msg->msg_flags & MSG_EOR)) @@ -1085,8 +1110,19 @@ static int tls_sw_sendmsg_locked(struct sock *sk, st= ruct msghdr *msg, full_record =3D true; } =20 + if (rec_zero_pad && !full_record) + zero_pad_len =3D record_room - try_to_copy; + + if (zero_pad_len > prot->tail_size) { + max_zero_pad_len =3D min(zero_pad_len, + tls_ctx->tx_record_zero_pad); + zero_pad_len =3D + get_random_u32_inclusive(0, max_zero_pad_len); + rec->zero_padding_len =3D zero_pad_len; + } + required_size =3D msg_pl->sg.size + try_to_copy + - prot->overhead_size; + prot->overhead_size + rec->zero_padding_len; =20 if (!sk_stream_memory_free(sk)) goto wait_for_sndbuf; @@ -2555,6 +2591,7 @@ void tls_sw_release_resources_tx(struct sock *sk) struct tls_rec, list); list_del(&rec->list); sk_msg_free(sk, &rec->msg_plaintext); + kfree(rec->zero_padding); kfree(rec); } =20 @@ -2562,6 +2599,7 @@ void tls_sw_release_resources_tx(struct sock *sk) list_del(&rec->list); sk_msg_free(sk, &rec->msg_encrypted); sk_msg_free(sk, &rec->msg_plaintext); + kfree(rec->zero_padding); kfree(rec); } =20 --=20 2.53.0 From nobody Thu Apr 9 12:06:20 2026 Received: from mail-pg1-f179.google.com (mail-pg1-f179.google.com [209.85.215.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3E2C834D393 for ; Mon, 9 Mar 2026 05:54:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773035688; cv=none; b=mDuxlH+q5Jv9KYwCu+IYb/J4KYXpEmuJyAw37XV8XGsw2RRVArla5z/2fT5wq/NS4kLtBSgr6Zj6taiVmLh7AUdMNg0xAH3giOvqLgiEr9Vf2eXL0Div1kQ6esCA99G7plftnPfWWI1hBBU6+iMJl6cYeX+8xnBEoyFLJIoj88k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773035688; c=relaxed/simple; bh=UreViDwj5CK4brJrjfQ7EURHubCS5eOib6jZhMepOdk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nxd7F3rRdFAd1OxtCC2Ocn2fRN8Z3ZKeNQigPvjRn9X6wl8xQlswySLERoitaoqaoV1MtVghHpZUAVpBLAIBv/X4xRR0OUcnafKVMlVE9hYAepIpErqGjabcyrhEyaSitPLkEdZpeu36KyntGEx5Ut9SOHh2gjCcmRH8MaJO6XI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=diN4NXLb; arc=none smtp.client-ip=209.85.215.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="diN4NXLb" Received: by mail-pg1-f179.google.com with SMTP id 41be03b00d2f7-c73aabd620bso944522a12.1 for ; Sun, 08 Mar 2026 22:54:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773035687; x=1773640487; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=+eXVlNI+VPppaY/morooabCwuSYEtf9ABnZ29jfqnh4=; b=diN4NXLbF4APbkdr50c/3buNpeiadWd82VxtjgPvoGcoRutc3j2Nu6wHNgxkIkqdBW YpXtsql8z0v6B5UM1N/XMPUdZ+HiZ9WoYIAMyAN7Nogld0k4WR4b0qmEW3gihjzXvLlt rGxenB7Pof6NqcF9rrbN6olzW6/MUZNQP/EA1n4AYKKND2xdCdKG2Kq9UtrC7lPlFDtT tZPnZmxaeAzXJVtdjiEQu1u0mzcySl7jJEZxGw6svm2rf1Rsdy69EP0sn5rS8tDx+1/J OTnrdUSrzf6ye0uEAJILUDvQoTxLo6qHy6pjaZtqoFWAUGLC8h3uH9lrTNC9/p5TllkG 5QrA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773035687; x=1773640487; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=+eXVlNI+VPppaY/morooabCwuSYEtf9ABnZ29jfqnh4=; b=m0zOh7wI+2BeqFDe7RI3XEYgy/qh0sqBbYzMjbupPIZma1U6la049X/XKlez6eI1Gf 2h2kys9bhj45SqllkVF9Tqr5YBQDsb5Q9Lz6e8Gv9Zv0/WRonHvN/Jx63OrNLEAbiJCv iaUAfIzaCDG1mjv3EERbkG/waVX3c3CUZ+uCuX3nztaaZWBSVH4BnKqk0+TzFFO30dFW Uy0Q/sEAfowCEDg9CobrQtdyI7yVb/ILBu/90mih4mvEzwf4x8F9/I+VHp9eYVSdsyh7 t8fvsRq4RkvDCOrjYLLdYEgCfTo+EoURPw/9ykgjnOdBLyD2UqL/L3xkcos4TohZY6s3 c5xw== X-Forwarded-Encrypted: i=1; AJvYcCWavxjKdaVwN6MschdOc42O+b+1VhNTvApzqRZ9pP3vc7XLo1AXoZrHJhxQfupYPgG7GDLxORhCx4NlUVE=@vger.kernel.org X-Gm-Message-State: AOJu0YyE/MmnMk8gN3a2et4ooMn5nG/icbcoZNU5BH/59LoBHFNENg/u 0k96IagEGH0aK/cjjeW+hTGw5Ke9Zv8c8rQPf46H75RrM0idAiu0CiZU X-Gm-Gg: ATEYQzw9zAYWD4mxkNslHfM5S59LHNiiuoj+ZHFUGMrfFEp09YsOnohdm0Ah1pTw0v8 /okRGtda2SSzc1xFkwkpBpwrdwJX16YiaLtmixa3XfVNtabottoLhA3457osFNBSRmvHA/nbjxX xJlIG650pZte3iZJ/GbqCJZT3oqpV7/6k/jtQVoVdJqxuaOfGUQAXDHwbvdPIdaVzt3uyJRfSkj b9jq5aymb3q+X4toAyc4+hNqXhQ59FivCNIIcN1ecAIl3eOqFwk1LnhSrx+ttMdxqsOV7qTlxB1 nw29LOzZIgMN6fQBWahxB3+rx4FAF8BIuAVDnFws2+yhWOo77rdRutqztvVaoAQT0laZBFPXDSv DBJU1wqMHiIUQ3fq1I15BIrDA/VCwqNaGSZtDl66fRSjUQq7eXbltGzOUOOFjCxscgbRiLFivh2 TKE2A+LO2Kt+qc/fXpVXpEas6FjXSDz8MTJdKLL9eAh854GWZ6qO8uxCfrvSrU X-Received: by 2002:a05:6a20:cf8b:b0:38e:90ca:5a4b with SMTP id adf61e73a8af0-39859089f98mr9851848637.45.1773035686645; Sun, 08 Mar 2026 22:54:46 -0700 (PDT) Received: from zenbook ([159.196.5.243]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-c739e170923sm7933716a12.17.2026.03.08.22.54.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Mar 2026 22:54:46 -0700 (PDT) From: Wilfred Mallawa To: John Fastabend , Jakub Kicinski , Sabrina Dubroca , "David S . Miller" , Eric Dumazet , Paolo Abeni , Simon Horman , Jonathan Corbet , Shuah Khan Cc: netdev@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Alistair Francis , Damien Le'Moal , Wilfred Mallawa Subject: [RFC net-next 2/3] net/tls: add randomized zero padding socket option Date: Mon, 9 Mar 2026 15:48:37 +1000 Message-ID: <20260309054837.2299732-4-wilfred.opensource@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309054837.2299732-2-wilfred.opensource@gmail.com> References: <20260309054837.2299732-2-wilfred.opensource@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Wilfred Mallawa Currently, for TLS 1.3, ktls does not support record zero padding [1]. Record zero padding is used to allow the sender to hide the size of the traffic patterns from an observer. TLS is susceptible to a variety of traff= ic analysis attacks based on observing the length and timing of encrypted packets [2]. Upcoming Western Digital NVMe-TCP hardware controllers implement TLS 1.3. Which from a security perspective, can benefit from havi= ng record zero padding enabled to mitigate against traffic analysis attacks [2]. Add a new TLS_TX_RANDOM_PAD ktls socket option that allows userspace to enable and specify an upperbound for randomized record zero padding in TLS 1.3. When this value is set and non-zero, ktls will append a randomized amount of [0, min(record_room, upper_bound)] bytes to records that are end-of-record (EOR) and aren't full. This can be set back to zero to disable appending zero padding. By default, no record zero padding is ad= ded. The number of zero padding bytes is randomised primarilly to reduce some of the throughput overhead of using a fixed zero padding amount up to the record size limit. [1] https://datatracker.ietf.org/doc/html/rfc8446#section-5.4l [2] https://datatracker.ietf.org/doc/html/rfc8446#appendix-E.3 Signed-off-by: Wilfred Mallawa --- Documentation/networking/tls.rst | 21 ++++++++++ include/uapi/linux/tls.h | 2 + net/tls/tls_main.c | 70 ++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+) diff --git a/Documentation/networking/tls.rst b/Documentation/networking/tl= s.rst index 980c442d7161..e112a68a9bfb 100644 --- a/Documentation/networking/tls.rst +++ b/Documentation/networking/tls.rst @@ -300,6 +300,27 @@ extra byte used by the ContentType field. =20 [1] https://datatracker.ietf.org/doc/html/rfc8449 =20 +TLS_TX_RANDOM_PAD +~~~~~~~~~~~~~~~~~ + +Enable and set the limit for randomized zero padding [1] of outgoing +TLS records. + +When enabled, TLS records that are not full and are end of record (EOR) +will be padded with a randomly chosen amount of zero padding up to the rem= aining +record capacity or the limit provided by this option (smaller of the two). +Randomized zero padding can reduce information leakage via observable TLS +record lengths and mitigates traffic analysis based on message size. + +Padding never exceeds the protocol maximum record size and full-sized reco= rds +are unchanged. + +This increases bandwidth usage and may add CPU overhead due to padding +generation and larger encryption operations. For workloads with small reco= rds, +the bandwidth overhead may be significant. + +[1] https://datatracker.ietf.org/doc/html/rfc8446#section-5.4 + Statistics =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 diff --git a/include/uapi/linux/tls.h b/include/uapi/linux/tls.h index b8b9c42f848c..42a318cb5eb8 100644 --- a/include/uapi/linux/tls.h +++ b/include/uapi/linux/tls.h @@ -42,6 +42,7 @@ #define TLS_TX_ZEROCOPY_RO 3 /* TX zerocopy (only sendfile now) */ #define TLS_RX_EXPECT_NO_PAD 4 /* Attempt opportunistic zero-copy */ #define TLS_TX_MAX_PAYLOAD_LEN 5 /* Maximum plaintext size */ +#define TLS_TX_RANDOM_PAD 6 /* TLS TX randomized record zero padding */ =20 /* Supported versions */ #define TLS_VERSION_MINOR(ver) ((ver) & 0xFF) @@ -196,6 +197,7 @@ enum { TLS_INFO_ZC_RO_TX, TLS_INFO_RX_NO_PAD, TLS_INFO_TX_MAX_PAYLOAD_LEN, + TLS_INFO_TX_RANDOM_PAD, __TLS_INFO_MAX, }; #define TLS_INFO_MAX (__TLS_INFO_MAX - 1) diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c index b0702effbc26..62c525afbc14 100644 --- a/net/tls/tls_main.c +++ b/net/tls/tls_main.c @@ -563,6 +563,30 @@ static int do_tls_getsockopt_tx_payload_len(struct soc= k *sk, char __user *optval return 0; } =20 +static int do_tls_getsockopt_tx_random_pad(struct sock *sk, char __user *o= ptval, + int __user *optlen) +{ + struct tls_context *ctx =3D tls_get_ctx(sk); + u16 pad_limit =3D ctx->tx_record_zero_pad; + int len; + + if (ctx->prot_info.version !=3D TLS_1_3_VERSION) + return -EOPNOTSUPP; + + if (get_user(len, optlen)) + return -EFAULT; + + if (len < sizeof(pad_limit)) + return -EINVAL; + + if (put_user(sizeof(pad_limit), optlen)) + return -EFAULT; + + if (copy_to_user(optval, &pad_limit, sizeof(pad_limit))) + return -EFAULT; + + return 0; +} static int do_tls_getsockopt(struct sock *sk, int optname, char __user *optval, int __user *optlen) { @@ -585,6 +609,9 @@ static int do_tls_getsockopt(struct sock *sk, int optna= me, case TLS_TX_MAX_PAYLOAD_LEN: rc =3D do_tls_getsockopt_tx_payload_len(sk, optval, optlen); break; + case TLS_TX_RANDOM_PAD: + rc =3D do_tls_getsockopt_tx_random_pad(sk, optval, optlen); + break; default: rc =3D -ENOPROTOOPT; break; @@ -860,6 +887,33 @@ static int do_tls_setsockopt_tx_payload_len(struct soc= k *sk, sockptr_t optval, return 0; } =20 +static int do_tls_setsockopt_tx_random_pad(struct sock *sk, sockptr_t optv= al, + unsigned int optlen) +{ + struct tls_context *ctx =3D tls_get_ctx(sk); + struct tls_sw_context_tx *sw_ctx =3D tls_sw_ctx_tx(ctx); + u16 value; + + if (ctx->prot_info.version !=3D TLS_1_3_VERSION) + return -EOPNOTSUPP; + + if (sw_ctx && sw_ctx->open_rec) + return -EBUSY; + + if (sockptr_is_null(optval) || optlen !=3D sizeof(value)) + return -EINVAL; + + if (copy_from_sockptr(&value, optval, sizeof(value))) + return -EFAULT; + + if (value >=3D ctx->tx_max_payload_len) + return -EINVAL; + + ctx->tx_record_zero_pad =3D value; + + return 0; +} + static int do_tls_setsockopt(struct sock *sk, int optname, sockptr_t optva= l, unsigned int optlen) { @@ -886,6 +940,11 @@ static int do_tls_setsockopt(struct sock *sk, int optn= ame, sockptr_t optval, rc =3D do_tls_setsockopt_tx_payload_len(sk, optval, optlen); release_sock(sk); break; + case TLS_TX_RANDOM_PAD: + lock_sock(sk); + rc =3D do_tls_setsockopt_tx_random_pad(sk, optval, optlen); + release_sock(sk); + break; default: rc =3D -ENOPROTOOPT; break; @@ -1173,6 +1232,13 @@ static int tls_get_info(struct sock *sk, struct sk_b= uff *skb, bool net_admin) if (err) goto nla_failure; =20 + if (version !=3D TLS_1_3_VERSION) { + err =3D nla_put_u16(skb, TLS_INFO_TX_RANDOM_PAD, + ctx->tx_record_zero_pad); + if (err) + goto nla_failure; + } + rcu_read_unlock(); nla_nest_end(skb, start); return 0; @@ -1185,6 +1251,7 @@ static int tls_get_info(struct sock *sk, struct sk_bu= ff *skb, bool net_admin) =20 static size_t tls_get_info_size(const struct sock *sk, bool net_admin) { + struct tls_context *ctx =3D tls_get_ctx(sk); size_t size =3D 0; =20 size +=3D nla_total_size(0) + /* INET_ULP_INFO_TLS */ @@ -1197,6 +1264,9 @@ static size_t tls_get_info_size(const struct sock *sk= , bool net_admin) nla_total_size(sizeof(u16)) + /* TLS_INFO_TX_MAX_PAYLOAD_LEN */ 0; =20 + if (ctx->prot_info.version =3D=3D TLS_1_3_VERSION) + size +=3D nla_total_size(sizeof(u16)); /* TLS_INFO_TX_RANDOM_PAD */ + return size; } =20 --=20 2.53.0 From nobody Thu Apr 9 12:06:20 2026 Received: from mail-pg1-f180.google.com (mail-pg1-f180.google.com [209.85.215.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1790B1E834E for ; Mon, 9 Mar 2026 05:54:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773035694; cv=none; b=gVX+wUxqZDjw5ManLpgwmIFVKV06Nn0daZkZGpRMd4Te8BjK/nK8T7mxUK7zZOpr2GWH00vP5ejMN0f+JjPxZWnTFX/P2w65BXfK2vX6bKEvU2nJ7o/HNyOY7dGZa3IhAQtbfT++xZV5PayVH+iH59M184HSjSIqzRqGw5wAoLc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773035694; c=relaxed/simple; bh=XCl+gIHDKVKF3BHAFazsPTr3zJzg68KTuSoHcRwyrs0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JGX++W5DnZs7qvomxV4CZm3fr+lBezYKKsKEqkw1uOIJZ5vobspUS/ePJFyF2tQjbf6shMZ/eWgxFPadmGcfq/Nk32qrXfwpph/Has/Xz2zDGPGtmxRD9nMkrB6/fxFHPUUNw7DpYmLrlpKBL35EZGuqk4WAv3Gh6LRehSjmBmU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=npuQ0r9Z; arc=none smtp.client-ip=209.85.215.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="npuQ0r9Z" Received: by mail-pg1-f180.google.com with SMTP id 41be03b00d2f7-c70e27e2b74so3421773a12.0 for ; Sun, 08 Mar 2026 22:54:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773035692; x=1773640492; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=32NNtnzDRxNT0zlaCXiiZQWhn0QJ3pzIuoI+2GweKqc=; b=npuQ0r9Z0ZQPOcBIPtFip/X+1du3ag+nP2jFJjm5c66ui8rviukW/tQ7rSgYDVRK4x BO/iSQbKDICI8WgjqBQLvCaukjC0IehGoMCnt1dPVsuzh5vTHXAEAePa9N1Vx9HJLC54 cBogATwH5/mwLWKFk7XxFFZa9gzj9iN+ZR8OttfaseIkDnSLvCBN1L1jQginitnTRdYW hQilOGIMTEDrqd7R9oEOdOrzzN03f4jRjXJtpU9sWvKKKCdaqgZQonbwglg9XiIv/0bA 7HAJXpJLAOCI4cQOBez9lnRhyjl5D2qsiKRBDEpiXZ8Po+yoiA5WOy43xHy/lVdT4pww aO0A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773035692; x=1773640492; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=32NNtnzDRxNT0zlaCXiiZQWhn0QJ3pzIuoI+2GweKqc=; b=A+zhKhCxKdz4joSgZPOJfx9dp6GUiMdNLi2TW/NcsnDb5XFjsXvksxyug0ficttsjg 1p8hHuPEfKp9FxjVTir5a4rjD7Iu7xkN776pDA4B/trc2Ue8rrtzuW+/oHxjiWkp2bdR 7PDvrQ1MJ1aZleq2DxiQi5iUbbuxjNhjx3q4GXKi+9u6cqlO4xOXReyUz7PA++inOo1j S5gbiN31Cc642v8VELkXc/Ab/BR2AQDNk5NqYI0Btt+BKeofJkJyMlf1YXNzO2IkxNM/ n9TtCoZvofSse005RcB0brlG/hpsSfP2zqEhuK6nVAJ3lhLWUpiTO/O41Wo8a1X+m/bR LcdA== X-Forwarded-Encrypted: i=1; AJvYcCUvzlA7eY7HYAUUysgTRqSR4syW0ZXX6LlIvDaYwn1mzITdEWN7zT1AfupxL1AXqeWWke4V99yqe8IhpPE=@vger.kernel.org X-Gm-Message-State: AOJu0YyXDdBWXJfs4jAt/efWgOz4B9AQobkT6QaycjkxE5uTAxAubMFs IM3UQerD1mEHsMI8SDb8ftmRE6FTovB9hMTu0UbiXHuioktyJBKXptqK X-Gm-Gg: ATEYQzyPMTRPonalBhWFgre7rojCmo/4olYxfBcgzS66b/wZZoIaZDBKumXjvbIda4z 1QDbdd9iCzTygdyLdCFrbPMCJarOorDTkBPpL3ZTJYo1nLnHJGhHapSZbUs3hkP2cs3VSyVazHx yfG1ePLUdqjBeNnK2+zksNJvsiSqosMemenwPpC1ksekwIfyR+vd7I3FHYPHT6Cg8+pnyDPEmSP XI5ifBr2DatfWUiHEZTEvoDFVRnu7OUme5kfDndJ2mcsAk5GdQCDVlBVEfZXSFiuYG2zC8rpfmD 3OUsOJmktrrqydzbyLSyU+zc5TQtQsmfJVeNLZuZ+SrcAqiKbpxQAEwD6ZyzUWZmqOq1OAq9X9c xypD7nI2iOuJTbs5g39IlfH6cx6f3trKZOEByfO7QtGW5nADjKqYU+ZESoWaiI/dyeRZjvYoJwq 1/w9wyhbXIOP8PIk8l1dl2blKBPjIG4E8X5G37GyZUKYuCUreZJuIilYfCsXON X-Received: by 2002:a05:6a20:1449:b0:35b:b508:b99f with SMTP id adf61e73a8af0-39858fb2c45mr8981210637.1.1773035692584; Sun, 08 Mar 2026 22:54:52 -0700 (PDT) Received: from zenbook ([159.196.5.243]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-c739e170923sm7933716a12.17.2026.03.08.22.54.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Mar 2026 22:54:52 -0700 (PDT) From: Wilfred Mallawa To: John Fastabend , Jakub Kicinski , Sabrina Dubroca , "David S . Miller" , Eric Dumazet , Paolo Abeni , Simon Horman , Jonathan Corbet , Shuah Khan Cc: netdev@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Alistair Francis , Damien Le'Moal , Wilfred Mallawa Subject: [RFC net-next 3/3] selftest: tls: add tls record zero pad test Date: Mon, 9 Mar 2026 15:48:38 +1000 Message-ID: <20260309054837.2299732-5-wilfred.opensource@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309054837.2299732-2-wilfred.opensource@gmail.com> References: <20260309054837.2299732-2-wilfred.opensource@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Wilfred Mallawa Enable record zero padding using the TLS_TX_RANDOM_PAD socket option for a TLS1.3 connection. This only tests the setsockopt()/getsockopt() invocations as padding is processed in the kernel. Signed-off-by: Wilfred Mallawa --- tools/testing/selftests/net/tls.c | 45 +++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/tools/testing/selftests/net/tls.c b/tools/testing/selftests/ne= t/tls.c index 9e2ccea13d70..a72ba8607ead 100644 --- a/tools/testing/selftests/net/tls.c +++ b/tools/testing/selftests/net/tls.c @@ -2997,6 +2997,51 @@ TEST(tls_12_tx_max_payload_len_open_rec) close(fd); } =20 +TEST(tls_13_tx_record_zero_padding) +{ + struct tls_crypto_info_keys tls13; + char const *tx =3D "how much wood could a woodchuck chuck"; + int tx_len =3D strlen(tx) + 1; + __u8 rx[4096]; + __u16 opt, zpad =3D 2048; + unsigned int optlen =3D sizeof(opt); + bool notls; + int ret, tx_fd, rx_fd; + + tls_crypto_info_init(TLS_1_3_VERSION, TLS_CIPHER_AES_GCM_128, + &tls13, 1); + + ulp_sock_pair(_metadata, &rx_fd, &tx_fd, ¬ls); + if (notls) + exit(KSFT_SKIP); + + /* Setup Keys */ + ret =3D setsockopt(tx_fd, SOL_TLS, TLS_TX, &tls13, tls13.len); + ASSERT_EQ(ret, 0); + + ret =3D setsockopt(rx_fd, SOL_TLS, TLS_RX, &tls13, tls13.len); + ASSERT_EQ(ret, 0); + + ret =3D setsockopt(tx_fd, SOL_TLS, TLS_TX_RANDOM_PAD, &zpad, + sizeof(zpad)); + ASSERT_EQ(ret, 0); + + ret =3D getsockopt(tx_fd, SOL_TLS, TLS_TX_RANDOM_PAD, &opt, &optlen); + EXPECT_EQ(ret, 0); + EXPECT_EQ(zpad, opt); + EXPECT_EQ(optlen, sizeof(zpad)); + + ASSERT_EQ(send(tx_fd, tx, tx_len, MSG_EOR), tx_len); + close(tx_fd); + + ret =3D recv(rx_fd, rx, sizeof(rx), 0); + ASSERT_GE(ret, 0); + ASSERT_LE(tx_len, ret); + EXPECT_EQ(memcmp(rx, tx, tx_len), 0); + + close(rx_fd); +} + TEST(non_established) { struct tls12_crypto_info_aes_gcm_256 tls12; struct sockaddr_in addr; --=20 2.53.0