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 <[email protected]>
---
 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


Reply via email to