[PATCH v2 10/13] rxrpc: implement wipe op for rxrpc keys

From: Jan Sebastian Götte

Date: Tue Aug 11 2026 - 14:29:12 EST


Wipe session keys and tickets of client key tokens, and add a server key
wipe op implemented by rxkad and rxgk.

Used by CONFIG_CRASH_WIPE_SECRETS.

Signed-off-by: Jan Sebastian Götte <linux@xxxxxxxx>
---
net/rxrpc/ar-internal.h | 5 +++++
net/rxrpc/key.c | 34 ++++++++++++++++++++++++++++++++++
net/rxrpc/rxgk.c | 11 +++++++++++
net/rxrpc/rxkad.c | 14 ++++++++++++++
net/rxrpc/server_key.c | 11 +++++++++++
5 files changed, 75 insertions(+)

diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index 865f05fe37ab..6466eb5a9929 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -282,6 +282,11 @@ struct rxrpc_security {
/* Destroy the payload of a server key */
void (*destroy_server_key)(struct key *);

+ /* Wipe the payload of a server key without freeing it. Used by
+ * CONFIG_CRASH_WIPE_SECRETS from the panic path.
+ */
+ void (*wipe_server_key)(struct key *);
+
/* Describe a server key */
void (*describe_server_key)(const struct key *, struct seq_file *);

diff --git a/net/rxrpc/key.c b/net/rxrpc/key.c
index a0aa78d89289..e612b7a8df13 100644
--- a/net/rxrpc/key.c
+++ b/net/rxrpc/key.c
@@ -11,6 +11,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
+#include <linux/crash_core.h>
#include <linux/net.h>
#include <linux/overflow.h>
#include <linux/skbuff.h>
@@ -26,6 +27,7 @@
static int rxrpc_preparse(struct key_preparsed_payload *);
static void rxrpc_free_preparse(struct key_preparsed_payload *);
static void rxrpc_destroy(struct key *);
+static void rxrpc_wipe(struct key *);
static void rxrpc_describe(const struct key *, struct seq_file *);
static long rxrpc_read(const struct key *, char *, size_t);

@@ -40,6 +42,7 @@ struct key_type key_type_rxrpc = {
.free_preparse = rxrpc_free_preparse,
.instantiate = generic_key_instantiate,
.destroy = rxrpc_destroy,
+ .wipe = rxrpc_wipe,
.describe = rxrpc_describe,
.read = rxrpc_read,
};
@@ -570,6 +573,31 @@ static void rxrpc_free_token_list(struct rxrpc_key_token *token)
}
}

+static void rxrpc_wipe_token_list(struct rxrpc_key_token *token)
+{
+ struct rxrpc_key_token *next;
+
+ for (; token; token = next) {
+ next = token->next;
+ switch (token->security_index) {
+ case RXRPC_SECURITY_RXKAD:
+ crash_wipe_memzero(token->kad->session_key,
+ sizeof(token->kad->session_key));
+ crash_wipe_memzero(token->kad->ticket,
+ token->kad->ticket_len);
+ break;
+ case RXRPC_SECURITY_YFS_RXGK:
+ crash_wipe_memzero(token->rxgk->key.data,
+ token->rxgk->key.len);
+ crash_wipe_memzero(token->rxgk->ticket.data,
+ token->rxgk->ticket.len);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
/*
* Clean up preparse data.
*/
@@ -586,6 +614,12 @@ static void rxrpc_destroy(struct key *key)
rxrpc_free_token_list(key->payload.data[0]);
}

+/* wipe the key without freeing. used by CONFIG_CRASH_WIPE_SECRETS. */
+static void rxrpc_wipe(struct key *key)
+{
+ rxrpc_wipe_token_list(key->payload.data[0]);
+}
+
/*
* describe the rxrpc key
*/
diff --git a/net/rxrpc/rxgk.c b/net/rxrpc/rxgk.c
index 77a67ace1d24..51c428fb3a60 100644
--- a/net/rxrpc/rxgk.c
+++ b/net/rxrpc/rxgk.c
@@ -8,6 +8,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/net.h>
+#include <linux/crash_core.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/key-type.h>
@@ -68,6 +69,15 @@ static void rxgk_destroy_server_key(struct key *key)
rxgk_free_server_key(&key->payload);
}

+/* wipe the key without freeing. used by CONFIG_CRASH_WIPE_SECRETS. */
+static void rxgk_wipe_server_key(struct key *key)
+{
+ struct krb5_buffer *server_key = (void *)&key->payload.data[2];
+
+ if (server_key->data)
+ crash_wipe_memzero(server_key->data, server_key->len);
+}
+
static void rxgk_describe_server_key(const struct key *key, struct seq_file *m)
{
const struct krb5_enctype *krb5 = key->payload.data[0];
@@ -1338,6 +1348,7 @@ const struct rxrpc_security rxgk_yfs = {
.preparse_server_key = rxgk_preparse_server_key,
.free_preparse_server_key = rxgk_free_preparse_server_key,
.destroy_server_key = rxgk_destroy_server_key,
+ .wipe_server_key = rxgk_wipe_server_key,
.describe_server_key = rxgk_describe_server_key,
.init_connection_security = rxgk_init_connection_security,
.alloc_txbuf = rxgk_alloc_txbuf,
diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c
index ca9f0e82cb9a..054ab67aca32 100644
--- a/net/rxrpc/rxkad.c
+++ b/net/rxrpc/rxkad.c
@@ -10,6 +10,7 @@
#include <crypto/des.h>
#include <kunit/visibility.h>
#include <linux/export.h>
+#include <linux/crash_core.h>
#include <linux/fips.h>
#include <linux/module.h>
#include <linux/net.h>
@@ -91,6 +92,18 @@ static void rxkad_destroy_server_key(struct key *key)
key->payload.data[0] = NULL;
}

+/* wipe the key without freeing. used by CONFIG_CRASH_WIPE_SECRETS. */
+static void rxkad_wipe_server_key(struct key *key)
+{
+ struct des_ctx *des_key = key->payload.data[0];
+
+ if (des_key)
+ crash_wipe_memzero(des_key, sizeof(*des_key));
+
+ /* the raw 8-byte key is kept inline in the payload union */
+ crash_wipe_memzero(&key->payload.data[2], 8);
+}
+
/*
* initialise connection security
*/
@@ -1127,6 +1140,7 @@ const struct rxrpc_security rxkad = {
.preparse_server_key = rxkad_preparse_server_key,
.free_preparse_server_key = rxkad_free_preparse_server_key,
.destroy_server_key = rxkad_destroy_server_key,
+ .wipe_server_key = rxkad_wipe_server_key,
.init_connection_security = rxkad_init_connection_security,
.alloc_txbuf = rxkad_alloc_txbuf,
.secure_packet = rxkad_secure_packet,
diff --git a/net/rxrpc/server_key.c b/net/rxrpc/server_key.c
index 3efe104b1930..a8e736d58793 100644
--- a/net/rxrpc/server_key.c
+++ b/net/rxrpc/server_key.c
@@ -26,6 +26,7 @@ static int rxrpc_vet_description_s(const char *);
static int rxrpc_preparse_s(struct key_preparsed_payload *);
static void rxrpc_free_preparse_s(struct key_preparsed_payload *);
static void rxrpc_destroy_s(struct key *);
+static void rxrpc_wipe_s(struct key *);
static void rxrpc_describe_s(const struct key *, struct seq_file *);

/*
@@ -40,6 +41,7 @@ struct key_type key_type_rxrpc_s = {
.free_preparse = rxrpc_free_preparse_s,
.instantiate = generic_key_instantiate,
.destroy = rxrpc_destroy_s,
+ .wipe = rxrpc_wipe_s,
.describe = rxrpc_describe_s,
};

@@ -105,6 +107,15 @@ static void rxrpc_destroy_s(struct key *key)
sec->destroy_server_key(key);
}

+/* wipe the key without freeing. used by CONFIG_CRASH_WIPE_SECRETS. */
+static void rxrpc_wipe_s(struct key *key)
+{
+ const struct rxrpc_security *sec = key->payload.data[1];
+
+ if (sec && sec->wipe_server_key)
+ sec->wipe_server_key(key);
+}
+
static void rxrpc_describe_s(const struct key *key, struct seq_file *m)
{
const struct rxrpc_security *sec = key->payload.data[1];

--
2.53.0