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

