[RFC net-next 1/3] net/tls_sw: support randomized zero padding

Wilfred Mallawa posted 3 patches 1 month ago
[RFC net-next 1/3] net/tls_sw: support randomized zero padding
Posted by Wilfred Mallawa 1 month ago
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>

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 traffic
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 having
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 <wilfred.mallawa@wdc.com>
---
 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;
 
 	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];
 
+	/* 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];
 
 	struct sock *sk;
 
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 = TLS_BASE;
 	ctx->rx_conf = TLS_BASE;
 	ctx->tx_max_payload_len = TLS_MAX_PAYLOAD_SIZE;
+	/* TX record zero padding is disabled by default */
+	ctx->tx_record_zero_pad = 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_rec *rec)
 {
 	sk_msg_free(sk, &rec->msg_encrypted);
 	sk_msg_free(sk, &rec->msg_plaintext);
+	kfree(rec->zero_padding);
 	kfree(rec);
 }
 
@@ -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);
 	}
 
@@ -450,6 +452,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);
 		} else {
 			break;
@@ -779,12 +782,29 @@ static int tls_push_record(struct sock *sk, int flags,
 	sk_msg_iter_var_prev(i);
 
 	rec->content_type = record_type;
+
 	if (prot->version == 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 = 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 = msg_en->sg.start;
 	sg_chain(rec->sg_aead_out, 2, &msg_en->sg.data[i]);
 
-	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);
 
 	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);
 
 	tls_ctx->pending_open_record_frags = false;
 
 	rc = 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 != -EINPROGRESS) {
 			tls_err_abort(sk, -EBADMSG);
@@ -1033,6 +1055,8 @@ static int tls_sw_sendmsg_locked(struct sock *sk, struct msghdr *msg,
 	unsigned char record_type = TLS_RECORD_TYPE_DATA;
 	bool is_kvec = iov_iter_is_kvec(&msg->msg_iter);
 	bool eor = !(msg->msg_flags & MSG_MORE);
+	bool tls_13 = (prot->version == TLS_1_3_VERSION);
+	bool rec_zero_pad = eor && tls_13 && tls_ctx->tx_record_zero_pad;
 	size_t try_to_copy;
 	ssize_t copied = 0;
 	struct sk_msg *msg_pl, *msg_en;
@@ -1043,6 +1067,7 @@ static int tls_sw_sendmsg_locked(struct sock *sk, struct msghdr *msg,
 	int record_room;
 	int num_zc = 0;
 	int orig_size;
+	int max_zero_pad_len, zero_pad_len = 0;
 	int ret = 0;
 
 	if (!eor && (msg->msg_flags & MSG_EOR))
@@ -1085,8 +1110,19 @@ static int tls_sw_sendmsg_locked(struct sock *sk, struct msghdr *msg,
 			full_record = true;
 		}
 
+		if (rec_zero_pad && !full_record)
+			zero_pad_len = record_room - try_to_copy;
+
+		if (zero_pad_len > prot->tail_size) {
+			max_zero_pad_len = min(zero_pad_len,
+					       tls_ctx->tx_record_zero_pad);
+			zero_pad_len =
+				get_random_u32_inclusive(0, max_zero_pad_len);
+			rec->zero_padding_len = zero_pad_len;
+		}
+
 		required_size = msg_pl->sg.size + try_to_copy +
-				prot->overhead_size;
+				prot->overhead_size + rec->zero_padding_len;
 
 		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);
 	}
 
@@ -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);
 	}
 
-- 
2.53.0
Re: [RFC net-next 1/3] net/tls_sw: support randomized zero padding
Posted by Sabrina Dubroca 3 weeks, 5 days ago
2026-03-09, 15:48:36 +1000, Wilfred Mallawa wrote:
> From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
> 
> 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 traffic
> 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 having
> 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

I don't think this is the right behavior. I expect that a user that
enables zero-padding would want _every_ record they send to be padded,
and their payload is going to be split into however many records that
requires. This could mean that data that would just fit in a record
will get split into one full + one very small record.

As it is, if I repeatedly call send with MSG_MORE to let ktls chunk
this for me, zero-padding has no effect. That doesn't seem right.

Does that make sense?

> 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

nit: there's a stray 'l' at the end of that link (and other references
to that section in your commit messages within the series)


> @@ -1033,6 +1055,8 @@ static int tls_sw_sendmsg_locked(struct sock *sk, struct msghdr *msg,
>  	unsigned char record_type = TLS_RECORD_TYPE_DATA;
>  	bool is_kvec = iov_iter_is_kvec(&msg->msg_iter);
>  	bool eor = !(msg->msg_flags & MSG_MORE);
> +	bool tls_13 = (prot->version == TLS_1_3_VERSION);
> +	bool rec_zero_pad = eor && tls_13 && tls_ctx->tx_record_zero_pad;

Thus here, rec_zero_pad would simply be tls_ctx->tx_record_zero_pad
(the tls_13 check should be redundant I think?).


> @@ -1085,8 +1110,19 @@ static int tls_sw_sendmsg_locked(struct sock *sk, struct msghdr *msg,
>  			full_record = true;
>  		}
>  
> +		if (rec_zero_pad && !full_record)
> +			zero_pad_len = record_room - try_to_copy;

And I would turn this logic the other way around:

 - decide zero_pad_len (get_random if that's the API approach we want,
   discussion in the cover letter) for every new record
 - adjust record_room based on that
 - then see if the record will be full


(I'll postpone looking at the actual implementation for now)

-- 
Sabrina
Re: [RFC net-next 1/3] net/tls_sw: support randomized zero padding
Posted by Wilfred Mallawa 3 weeks, 2 days ago
On Fri, 2026-03-13 at 14:16 +0100, Sabrina Dubroca wrote:
> 2026-03-09, 15:48:36 +1000, Wilfred Mallawa wrote:
> > From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
> > 
> > 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 traffic
> > 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 having
> > 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
> 
> I don't think this is the right behavior. I expect that a user that
> enables zero-padding would want _every_ record they send to be
> padded,
> and their payload is going to be split into however many records that
> requires. This could mean that data that would just fit in a record
> will get split into one full + one very small record.
> 
> As it is, if I repeatedly call send with MSG_MORE to let ktls chunk
> this for me, zero-padding has no effect. That doesn't seem right.
> 
> Does that make sense?
> 

hmm it does... but also, I am not sure if chunking records solely to
introduce zero padding is a good idea either? is the added overhead
worth it? For example, the NVMe TCP/TLS usecase, I think this would
slow things down noticeably. The current approach is meant to be a
balance between some of the security benefits and performance.

But as you mentioned, we can introduce a fixed size option, such that
all outgoing records are padded to the max record size. Which should
address security concern the above (?) ... at the cost of performance,
this provides a stronger padding policy, and would keep the logic quite
simple?

For context, testing with NVMe TCP TLS we saw a ~50% reduction in
performance (4K Write IOPs) when padding all outgoing records to the
maximum record size limit. 

> > 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
> 
> nit: there's a stray 'l' at the end of that link (and other
> references
> to that section in your commit messages within the series)
> 

oops! missed that... thanks!

> 
> > @@ -1033,6 +1055,8 @@ static int tls_sw_sendmsg_locked(struct sock
> > *sk, struct msghdr *msg,
> >  	unsigned char record_type = TLS_RECORD_TYPE_DATA;
> >  	bool is_kvec = iov_iter_is_kvec(&msg->msg_iter);
> >  	bool eor = !(msg->msg_flags & MSG_MORE);
> > +	bool tls_13 = (prot->version == TLS_1_3_VERSION);
> > +	bool rec_zero_pad = eor && tls_13 && tls_ctx-
> > >tx_record_zero_pad;
> 
> Thus here, rec_zero_pad would simply be tls_ctx->tx_record_zero_pad
> (the tls_13 check should be redundant I think?).

Ah yes, it is checked in the setsockopt()!


Wilfred
Re: [RFC net-next 1/3] net/tls_sw: support randomized zero padding
Posted by Jakub Kicinski 3 weeks, 4 days ago
On Fri, 13 Mar 2026 14:16:10 +0100 Sabrina Dubroca wrote:
> 2026-03-09, 15:48:36 +1000, Wilfred Mallawa wrote:
> > From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
> > 
> > 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 traffic
> > 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 having
> > 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  
> 
> I don't think this is the right behavior. I expect that a user that
> enables zero-padding would want _every_ record they send to be padded,
> and their payload is going to be split into however many records that
> requires. This could mean that data that would just fit in a record
> will get split into one full + one very small record.
> 
> As it is, if I repeatedly call send with MSG_MORE to let ktls chunk
> this for me, zero-padding has no effect. That doesn't seem right.
> 
> Does that make sense?

Or maybe you could refer to existing implementations of this feature
in user space libs? The padding feature seems slightly nebulous, 
I wasn't aware of anyone actually using it. Maybe I should ask...
are you actually planning to use it, or are you checking a box?

Second question - do we also need to support zero-byte records (entire
record is padding) to prevent timing attacks?
Re: [RFC net-next 1/3] net/tls_sw: support randomized zero padding
Posted by Wilfred Mallawa 3 weeks, 2 days ago
On Sat, 2026-03-14 at 07:39 -0700, Jakub Kicinski wrote:
> On Fri, 13 Mar 2026 14:16:10 +0100 Sabrina Dubroca wrote:
> > 2026-03-09, 15:48:36 +1000, Wilfred Mallawa wrote:
> > > From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
> > > 
> > > 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 traffic
> > > 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 having
> > > 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  
> > 
> > I don't think this is the right behavior. I expect that a user that
> > enables zero-padding would want _every_ record they send to be
> > padded,
> > and their payload is going to be split into however many records
> > that
> > requires. This could mean that data that would just fit in a record
> > will get split into one full + one very small record.
> > 
> > As it is, if I repeatedly call send with MSG_MORE to let ktls chunk
> > this for me, zero-padding has no effect. That doesn't seem right.
> > 
> > Does that make sense?
> 
> Or maybe you could refer to existing implementations of this feature
> in user space libs? The padding feature seems slightly nebulous, 
> I wasn't aware of anyone actually using it. Maybe I should ask...
> are you actually planning to use it, or are you checking a box?

For upcoming WD hardware, we were planning on informing users to use
this feature if an extra layer of security can benefit their particular
configuration. But to answer your question, I think this falls more
into the "checking a box"...

I'm happy to drop this series if there's not much added value from
having this as an available option for users.

> 
> Second question - do we also need to support zero-byte records
> (entire
> record is padding) to prevent timing attacks?

That's a good point, although it is not needed, having it could benefit
in timing attacks. As RFC8446 [1] puts it, 
"This permits generation of plausibly sized cover traffic in contexts
where the presence or absence of activity may be sensitive."

I can look into that if we are going ahead with this series...

Regards,
Wilfred

[1] https://datatracker.ietf.org/doc/html/rfc8446#section-5.4
Re: [RFC net-next 1/3] net/tls_sw: support randomized zero padding
Posted by Jakub Kicinski 3 weeks, 2 days ago
On Tue, 17 Mar 2026 00:53:07 +0000 Wilfred Mallawa wrote:
> > Or maybe you could refer to existing implementations of this feature
> > in user space libs? The padding feature seems slightly nebulous, 
> > I wasn't aware of anyone actually using it. Maybe I should ask...
> > are you actually planning to use it, or are you checking a box?  
> 
> For upcoming WD hardware, we were planning on informing users to use
> this feature if an extra layer of security can benefit their particular
> configuration. But to answer your question, I think this falls more
> into the "checking a box"...
> 
> I'm happy to drop this series if there's not much added value from
> having this as an available option for users.

I'm not much of a security person, and maybe Sabrina will disagree
but I feel like it's going to be hard for us to design this feature
in a sensible way if we don't know at least one potential attack :S
Re: [RFC net-next 1/3] net/tls_sw: support randomized zero padding
Posted by Sabrina Dubroca 3 weeks, 2 days ago
2026-03-16, 18:03:55 -0700, Jakub Kicinski wrote:
> On Tue, 17 Mar 2026 00:53:07 +0000 Wilfred Mallawa wrote:
> > > Or maybe you could refer to existing implementations of this feature
> > > in user space libs? The padding feature seems slightly nebulous, 
> > > I wasn't aware of anyone actually using it. Maybe I should ask...
> > > are you actually planning to use it, or are you checking a box?  
> > 
> > For upcoming WD hardware, we were planning on informing users to use
> > this feature if an extra layer of security can benefit their particular
> > configuration. But to answer your question, I think this falls more
> > into the "checking a box"...
> > 
> > I'm happy to drop this series if there's not much added value from
> > having this as an available option for users.
> 
> I'm not much of a security person, and maybe Sabrina will disagree
> but I feel like it's going to be hard for us to design this feature
> in a sensible way if we don't know at least one potential attack :S

No, same here, that's why I tried to CC some userspace developers on
the cover (as well as for awareness of what's going on in the kernel
and the API being discussed -- adding them here again).

My understanding is that attacks of this type are mainly "observers
will figure out what type of traffic I'm doing based on message
length", and I feel all those "traffic pattern masking" features are
only interesting for very paranoid users. The RFC links to some
research, and maybe the kind of statistics/machine learning that those
attacks require has improved since, which could make such attacks more
realistic? No idea.

-- 
Sabrina
Re: [RFC net-next 1/3] net/tls_sw: support randomized zero padding
Posted by Wilfred Mallawa 3 weeks, 2 days ago
On Mon, 2026-03-16 at 18:03 -0700, Jakub Kicinski wrote:
> On Tue, 17 Mar 2026 00:53:07 +0000 Wilfred Mallawa wrote:
> > > Or maybe you could refer to existing implementations of this
> > > feature
> > > in user space libs? The padding feature seems slightly nebulous, 
> > > I wasn't aware of anyone actually using it. Maybe I should ask...
> > > are you actually planning to use it, or are you checking a box?  
> > 
> > For upcoming WD hardware, we were planning on informing users to
> > use
> > this feature if an extra layer of security can benefit their
> > particular
> > configuration. But to answer your question, I think this falls more
> > into the "checking a box"...
> > 
> > I'm happy to drop this series if there's not much added value from
> > having this as an available option for users.
> 
> I'm not much of a security person, and maybe Sabrina will disagree
> but I feel like it's going to be hard for us to design this feature
> in a sensible way if we don't know at least one potential attack :S

Traffic analysis is the attack vector we are trying to mitigate against
with zero padding, which TLS is susceptible to [1]. I think the hard
part is deciding the padding policy and balancing it such that we have
sensible performance.

This series adds random padding to records with room, a stronger policy
I think would be to pad all records to max record size length. But that
adds a much higher performance overhead. For context, when testing NVMe
TCP+TLS with 4K writes with a record size limit of 4k, we observed a
50% reduction in IOPs on the fixed max record pad policy as opposed to
the random padding policy from this series.

Wilfred

[1] https://datatracker.ietf.org/doc/html/rfc8446#appendix-E.3
Re: [RFC net-next 1/3] net/tls_sw: support randomized zero padding
Posted by Jakub Kicinski 3 weeks, 2 days ago
On Tue, 17 Mar 2026 01:21:12 +0000 Wilfred Mallawa wrote:
> On Mon, 2026-03-16 at 18:03 -0700, Jakub Kicinski wrote:
> > On Tue, 17 Mar 2026 00:53:07 +0000 Wilfred Mallawa wrote:  
>  [...]  
> > > 
> > > For upcoming WD hardware, we were planning on informing users to
> > > use
> > > this feature if an extra layer of security can benefit their
> > > particular
> > > configuration. But to answer your question, I think this falls more
> > > into the "checking a box"...
> > > 
> > > I'm happy to drop this series if there's not much added value from
> > > having this as an available option for users.  
> > 
> > I'm not much of a security person, and maybe Sabrina will disagree
> > but I feel like it's going to be hard for us to design this feature
> > in a sensible way if we don't know at least one potential attack :S  
> 
> Traffic analysis is the attack vector we are trying to mitigate against
> with zero padding, which TLS is susceptible to [1]. I think the hard
> part is deciding the padding policy and balancing it such that we have
> sensible performance.
> 
> This series adds random padding to records with room, a stronger policy
> I think would be to pad all records to max record size length. But that
> adds a much higher performance overhead. For context, when testing NVMe
> TCP+TLS with 4K writes with a record size limit of 4k, we observed a
> 50% reduction in IOPs on the fixed max record pad policy as opposed to
> the random padding policy from this series.

Sorry, I realized when i hit "send" that I phrased my previous message
poorly. When I say "potential" I mean someone actually presenting a PoC
and a CVE is issued for it. Have we seen any of those?
Re: [RFC net-next 1/3] net/tls_sw: support randomized zero padding
Posted by Wilfred Mallawa 3 weeks, 2 days ago
On Mon, 2026-03-16 at 18:30 -0700, Jakub Kicinski wrote:
> On Tue, 17 Mar 2026 01:21:12 +0000 Wilfred Mallawa wrote:
> > On Mon, 2026-03-16 at 18:03 -0700, Jakub Kicinski wrote:
> > > On Tue, 17 Mar 2026 00:53:07 +0000 Wilfred Mallawa wrote:  
> >  [...]  
> > > > 
> > > > For upcoming WD hardware, we were planning on informing users
> > > > to
> > > > use
> > > > this feature if an extra layer of security can benefit their
> > > > particular
> > > > configuration. But to answer your question, I think this falls
> > > > more
> > > > into the "checking a box"...
> > > > 
> > > > I'm happy to drop this series if there's not much added value
> > > > from
> > > > having this as an available option for users.  
> > > 
> > > I'm not much of a security person, and maybe Sabrina will
> > > disagree
> > > but I feel like it's going to be hard for us to design this
> > > feature
> > > in a sensible way if we don't know at least one potential attack
> > > :S  
> > 
> > Traffic analysis is the attack vector we are trying to mitigate
> > against
> > with zero padding, which TLS is susceptible to [1]. I think the
> > hard
> > part is deciding the padding policy and balancing it such that we
> > have
> > sensible performance.
> > 
> > This series adds random padding to records with room, a stronger
> > policy
> > I think would be to pad all records to max record size length. But
> > that
> > adds a much higher performance overhead. For context, when testing
> > NVMe
> > TCP+TLS with 4K writes with a record size limit of 4k, we observed
> > a
> > 50% reduction in IOPs on the fixed max record pad policy as opposed
> > to
> > the random padding policy from this series.
> 
> Sorry, I realized when i hit "send" that I phrased my previous
> message
> poorly. When I say "potential" I mean someone actually presenting a
> PoC
> and a CVE is issued for it. Have we seen any of those?

Ah right, I haven't seen any PoC/CVEs which could directly be addressed
by zero padding.

Wilfred
Re: [RFC net-next 1/3] net/tls_sw: support randomized zero padding
Posted by Alistair Francis 3 weeks ago
On Tue, 2026-03-17 at 01:53 +0000, Wilfred Mallawa wrote:
> On Mon, 2026-03-16 at 18:30 -0700, Jakub Kicinski wrote:
> > On Tue, 17 Mar 2026 01:21:12 +0000 Wilfred Mallawa wrote:
> > > On Mon, 2026-03-16 at 18:03 -0700, Jakub Kicinski wrote:
> > > > On Tue, 17 Mar 2026 00:53:07 +0000 Wilfred Mallawa wrote:  
> > >  [...]  
> > > > > 
> > > > > For upcoming WD hardware, we were planning on informing users
> > > > > to
> > > > > use
> > > > > this feature if an extra layer of security can benefit their
> > > > > particular
> > > > > configuration. But to answer your question, I think this
> > > > > falls
> > > > > more
> > > > > into the "checking a box"...
> > > > > 
> > > > > I'm happy to drop this series if there's not much added value
> > > > > from
> > > > > having this as an available option for users.  
> > > > 
> > > > I'm not much of a security person, and maybe Sabrina will
> > > > disagree
> > > > but I feel like it's going to be hard for us to design this
> > > > feature
> > > > in a sensible way if we don't know at least one potential
> > > > attack
> > > > :S  
> > > 
> > > Traffic analysis is the attack vector we are trying to mitigate
> > > against
> > > with zero padding, which TLS is susceptible to [1]. I think the
> > > hard
> > > part is deciding the padding policy and balancing it such that we
> > > have
> > > sensible performance.
> > > 
> > > This series adds random padding to records with room, a stronger
> > > policy
> > > I think would be to pad all records to max record size length.
> > > But
> > > that
> > > adds a much higher performance overhead. For context, when
> > > testing
> > > NVMe
> > > TCP+TLS with 4K writes with a record size limit of 4k, we
> > > observed
> > > a
> > > 50% reduction in IOPs on the fixed max record pad policy as
> > > opposed
> > > to
> > > the random padding policy from this series.
> > 
> > Sorry, I realized when i hit "send" that I phrased my previous
> > message
> > poorly. When I say "potential" I mean someone actually presenting a
> > PoC
> > and a CVE is issued for it. Have we seen any of those?

In 2014 a group at UC Berkeley used HTTPS traffic analysis to identify:

"individual pages in the same web-site with 90% accuracy, exposing
personal details including medical conditions, financial and legal
affairs and sexual orientation."

They used machine learning to help and that was over 10 years ago. So I
suspect modern day machine learning would make this even easier to do
today.

Obviously that is HTTP traffic, which is different to the NVMe-TCP
traffic this series is targeting, but it does still seem like a real
concern.

They talk about a range of defences in the paper, with tradeoffs
between all of them. But the linear defence seems like the one that is
applicable here:

"linear defense pads all packet sizes up to multiples of 128"

The linear defence seems to reduce the Pan attack from 60% to around
25% and the BoG attack from 90% to around 60%.

On top of that the

"Burst defense offers greater protection, operating between the TCP
layer and application layer to pad contiguous bursts of traffic up to 
predefined thresholds uniquely determined for each website"

Which to me sounds like the random padding proposed in this series
would provide more protection then the basic linear padding used in the
paper.

To me analysing TLS traffic does seem like a plausible threat and
something that randomised padding would help with. Leaving it up to
userspace to decide based on their threat model seems like a good
approach as well.

1: https://secml.cs.berkeley.edu/pets2014/

Alistair

> 
> Ah right, I haven't seen any PoC/CVEs which could directly be
> addressed
> by zero padding.
> 
> Wilfred