[PATCH net-next 12/23] rxrpc: Allow for a security trailer in a packet

From: David Howells
Date: Thu Oct 01 2020 - 10:58:37 EST


Allow for a security trailer to added to a packet. The size is stored in
conn->security_trailer. Note any size alignment set by the security class
must be applied after subtracting the trailer (but the alignment includes
the security header, which is assumed to be encrypted).

Signed-off-by: David Howells <dhowells@xxxxxxxxxx>
---

net/rxrpc/ar-internal.h | 1 +
net/rxrpc/sendmsg.c | 28 ++++++++++++++++------------
2 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index dce48162f6c2..5aacd6d7cf28 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -455,6 +455,7 @@ struct rxrpc_connection {
u32 service_id; /* Service ID, possibly upgraded */
u8 size_align; /* data size alignment (for security) */
u8 security_size; /* security header size */
+ u8 security_trailer; /* Security trailer size */
u8 security_ix; /* security type */
u8 out_clientflag; /* RXRPC_CLIENT_INITIATED if we are client */
u8 bundle_shift; /* Index into bundle->avail_chans */
diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c
index d27140c836cc..258224bb1227 100644
--- a/net/rxrpc/sendmsg.c
+++ b/net/rxrpc/sendmsg.c
@@ -327,7 +327,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
rxrpc_send_ack_packet(call, false, NULL);

if (!skb) {
- size_t size, chunk, max, space;
+ size_t size, chunk, limit, space, shdr;

_debug("alloc");

@@ -342,18 +342,22 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
goto maybe_error;
}

- max = RXRPC_JUMBO_DATALEN;
- max -= call->conn->security_size;
- max &= ~(call->conn->size_align - 1UL);
-
- chunk = max;
- if (chunk > msg_data_left(msg) && !more)
+ /* Work out the maximum size of a packet. Assume that
+ * the security header is going to be in the padded
+ * region (enc blocksize), but the trailer is not.
+ */
+ shdr = call->conn->security_size;
+ limit = RXRPC_JUMBO_DATALEN;
+ limit -= call->conn->security_trailer;
+ space = round_down(limit, call->conn->size_align);
+
+ chunk = space - shdr;
+ if (msg_data_left(msg) < chunk && !more) {
chunk = msg_data_left(msg);
+ space = round_up(shdr + chunk, call->conn->size_align);
+ }

- space = chunk + call->conn->size_align;
- space &= ~(call->conn->size_align - 1UL);
-
- size = space + call->conn->security_size;
+ size = space + call->conn->security_trailer;

_debug("SIZE: %zu/%zu/%zu", chunk, space, size);

@@ -425,7 +429,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
size_t pad;

/* pad out if we're using security */
- if (conn->security_ix) {
+ if (conn->size_align > 0) {
pad = conn->security_size + skb->mark;
pad = conn->size_align - pad;
pad &= conn->size_align - 1;