Commit 9d1d2b59 authored by David Howells's avatar David Howells Committed by Jakub Kicinski
Browse files

rxrpc: rxgk: Implement the yfs-rxgk security class (GSSAPI)



Implement the basic parts of the yfs-rxgk security class (security index 6)
to support GSSAPI-negotiated security.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: Chuck Lever <chuck.lever@oracle.com>
cc: Simon Horman <horms@kernel.org>
cc: linux-afs@lists.infradead.org
Link: https://patch.msgid.link/20250411095303.2316168-9-dhowells@redhat.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent c86f9b96
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1182,6 +1182,7 @@ API Function Reference
.. kernel-doc:: net/rxrpc/oob.c
.. kernel-doc:: net/rxrpc/peer_object.c
.. kernel-doc:: net/rxrpc/recvmsg.c
.. kernel-doc:: net/rxrpc/rxgk.c
.. kernel-doc:: net/rxrpc/rxkad.c
.. kernel-doc:: net/rxrpc/sendmsg.c
.. kernel-doc:: net/rxrpc/server_key.c
+12 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
 */

#include <linux/slab.h>
#include <crypto/krb5.h>
#include "internal.h"
#include "afs_fs.h"
#include "protocol_yfs.h"
@@ -17,6 +18,9 @@
 */
static int afs_respond_to_challenge(struct sk_buff *challenge)
{
#ifdef CONFIG_RXGK
	struct krb5_buffer appdata = {};
#endif
	struct rxrpc_peer *peer;
	unsigned long peer_data;
	u16 service_id;
@@ -44,8 +48,16 @@ static int afs_respond_to_challenge(struct sk_buff *challenge)
	}

	switch (security_index) {
#ifdef CONFIG_RXKAD
	case RXRPC_SECURITY_RXKAD:
		return rxkad_kernel_respond_to_challenge(challenge);
#endif

#ifdef CONFIG_RXGK
	case RXRPC_SECURITY_RXGK:
	case RXRPC_SECURITY_YFS_RXGK:
		return rxgk_kernel_respond_to_challenge(challenge, &appdata);
#endif

	default:
		return rxrpc_kernel_reject_challenge(challenge, RX_USER_ABORT, -EPROTO,
+43 −2
Original line number Diff line number Diff line
@@ -69,6 +69,38 @@
	EM(rxkad_abort_resp_tkt_sname,		"rxkad-resp-tk-sname")	\
	EM(rxkad_abort_resp_unknown_tkt,	"rxkad-resp-unknown-tkt") \
	EM(rxkad_abort_resp_version,		"rxkad-resp-version")	\
	/* RxGK security errors */					\
	EM(rxgk_abort_1_verify_mic_eproto,	"rxgk1-vfy-mic-eproto")	\
	EM(rxgk_abort_2_decrypt_eproto,		"rxgk2-dec-eproto")	\
	EM(rxgk_abort_2_short_data,		"rxgk2-short-data")	\
	EM(rxgk_abort_2_short_encdata,		"rxgk2-short-encdata")	\
	EM(rxgk_abort_2_short_header,		"rxgk2-short-hdr")	\
	EM(rxgk_abort_bad_key_number,		"rxgk-bad-key-num")	\
	EM(rxgk_abort_chall_key_expired,	"rxgk-chall-key-exp")	\
	EM(rxgk_abort_chall_no_key,		"rxgk-chall-nokey")	\
	EM(rxgk_abort_chall_short,		"rxgk-chall-short")	\
	EM(rxgk_abort_resp_auth_dec,		"rxgk-resp-auth-dec")	\
	EM(rxgk_abort_resp_bad_callid,		"rxgk-resp-bad-callid")	\
	EM(rxgk_abort_resp_bad_nonce,		"rxgk-resp-bad-nonce")	\
	EM(rxgk_abort_resp_bad_param,		"rxgk-resp-bad-param")	\
	EM(rxgk_abort_resp_call_ctr,		"rxgk-resp-call-ctr")	\
	EM(rxgk_abort_resp_call_state,		"rxgk-resp-call-state")	\
	EM(rxgk_abort_resp_internal_error,	"rxgk-resp-int-error")	\
	EM(rxgk_abort_resp_nopkg,		"rxgk-resp-nopkg")	\
	EM(rxgk_abort_resp_short_applen,	"rxgk-resp-short-applen") \
	EM(rxgk_abort_resp_short_auth,		"rxgk-resp-short-auth") \
	EM(rxgk_abort_resp_short_call_list,	"rxgk-resp-short-callls") \
	EM(rxgk_abort_resp_short_packet,	"rxgk-resp-short-packet") \
	EM(rxgk_abort_resp_short_yfs_klen,	"rxgk-resp-short-yfs-klen") \
	EM(rxgk_abort_resp_short_yfs_key,	"rxgk-resp-short-yfs-key") \
	EM(rxgk_abort_resp_short_yfs_tkt,	"rxgk-resp-short-yfs-tkt") \
	EM(rxgk_abort_resp_tok_dec,		"rxgk-resp-tok-dec")	\
	EM(rxgk_abort_resp_tok_internal_error,	"rxgk-resp-tok-int-err") \
	EM(rxgk_abort_resp_tok_keyerr,		"rxgk-resp-tok-keyerr")	\
	EM(rxgk_abort_resp_tok_nokey,		"rxgk-resp-tok-nokey")	\
	EM(rxgk_abort_resp_tok_nopkg,		"rxgk-resp-tok-nopkg")	\
	EM(rxgk_abort_resp_tok_short,		"rxgk-resp-tok-short")	\
	EM(rxgk_abort_resp_xdr_align,		"rxgk-resp-xdr-align")	\
	/* rxrpc errors */						\
	EM(rxrpc_abort_call_improper_term,	"call-improper-term")	\
	EM(rxrpc_abort_call_reset,		"call-reset")		\
@@ -471,6 +503,7 @@
	EM(rxrpc_tx_point_call_final_resend,	"CallFinalResend") \
	EM(rxrpc_tx_point_conn_abort,		"ConnAbort") \
	EM(rxrpc_tx_point_reject,		"Reject") \
	EM(rxrpc_tx_point_rxgk_challenge,	"RxGKChall") \
	EM(rxrpc_tx_point_rxkad_challenge,	"RxkadChall") \
	EM(rxrpc_tx_point_response,		"Response") \
	EM(rxrpc_tx_point_version_keepalive,	"VerKeepalive") \
@@ -489,6 +522,7 @@

#define rxrpc_txbuf_traces \
	EM(rxrpc_txbuf_alloc_data,		"ALLOC DATA ")	\
	EM(rxrpc_txbuf_alloc_response,		"ALLOC RESP ")	\
	EM(rxrpc_txbuf_free,			"FREE       ")	\
	EM(rxrpc_txbuf_get_buffer,		"GET BUFFER ")	\
	EM(rxrpc_txbuf_get_trans,		"GET TRANS  ")	\
@@ -496,6 +530,7 @@
	EM(rxrpc_txbuf_put_cleaned,		"PUT CLEANED")	\
	EM(rxrpc_txbuf_put_nomem,		"PUT NOMEM  ")	\
	EM(rxrpc_txbuf_put_rotated,		"PUT ROTATED")	\
	EM(rxrpc_txbuf_put_response_tx,		"PUT RESP TX")	\
	EM(rxrpc_txbuf_put_send_aborted,	"PUT SEND-X ")	\
	EM(rxrpc_txbuf_put_trans,		"PUT TRANS  ")	\
	EM(rxrpc_txbuf_see_lost,		"SEE LOST   ")	\
@@ -1178,6 +1213,7 @@ TRACE_EVENT(rxrpc_rx_challenge,
		    __field(u32,		version)
		    __field(u32,		nonce)
		    __field(u32,		min_level)
		    __field(u8,			security_ix)
			     ),

	    TP_fast_assign(
@@ -1186,11 +1222,13 @@ TRACE_EVENT(rxrpc_rx_challenge,
		    __entry->version = version;
		    __entry->nonce = nonce;
		    __entry->min_level = min_level;
		    __entry->security_ix = conn->security_ix;
			   ),

	    TP_printk("C=%08x CHALLENGE %08x v=%x n=%x ml=%x",
	    TP_printk("C=%08x CHALLENGE r=%08x sx=%u v=%x n=%x ml=%x",
		      __entry->conn,
		      __entry->serial,
		      __entry->security_ix,
		      __entry->version,
		      __entry->nonce,
		      __entry->min_level)
@@ -1208,6 +1246,7 @@ TRACE_EVENT(rxrpc_rx_response,
		    __field(u32,		version)
		    __field(u32,		kvno)
		    __field(u32,		ticket_len)
		    __field(u8,			security_ix)
			     ),

	    TP_fast_assign(
@@ -1216,11 +1255,13 @@ TRACE_EVENT(rxrpc_rx_response,
		    __entry->version = version;
		    __entry->kvno = kvno;
		    __entry->ticket_len = ticket_len;
		    __entry->security_ix = conn->security_ix;
			   ),

	    TP_printk("C=%08x RESPONSE %08x v=%x kvno=%x tl=%x",
	    TP_printk("C=%08x RESPONSE r=%08x sx=%u v=%x kvno=%x tl=%x",
		      __entry->conn,
		      __entry->serial,
		      __entry->security_ix,
		      __entry->version,
		      __entry->kvno,
		      __entry->ticket_len)
+2 −0
Original line number Diff line number Diff line
@@ -41,6 +41,8 @@ rxrpc-$(CONFIG_PROC_FS) += proc.o
rxrpc-$(CONFIG_RXKAD) += rxkad.o
rxrpc-$(CONFIG_SYSCTL) += sysctl.o
rxrpc-$(CONFIG_RXGK) += \
	rxgk.o \
	rxgk_app.o \
	rxgk_kdf.o

obj-$(CONFIG_RXPERF) += rxperf.o
+17 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ struct key_preparsed_payload;
struct rxrpc_connection;
struct rxrpc_txbuf;
struct rxrpc_txqueue;
struct rxgk_context;

/*
 * Mark applied to socket buffers in skb->mark.  skb->priority is used
@@ -312,6 +313,11 @@ struct rxrpc_security {

	/* clear connection security */
	void (*clear)(struct rxrpc_connection *);

	/* Default ticket -> key decoder */
	int (*default_decode_ticket)(struct rxrpc_connection *conn, struct sk_buff *skb,
				     unsigned int ticket_offset, unsigned int ticket_len,
				     struct key **_key);
};

/*
@@ -559,7 +565,10 @@ struct rxrpc_connection {
			u32	nonce;		/* response re-use preventer */
		} rxkad;
		struct {
			struct rxgk_context *keys[1];
			u64	start_time;	/* The start time for TK derivation */
			u8	nonce[20];	/* Response re-use preventer */
			u32	enctype;	/* Kerberos 5 encoding type */
		} rxgk;
	};
	struct sk_buff		*tx_response;	/* Response packet to be transmitted */
@@ -903,6 +912,8 @@ struct rxrpc_txbuf {
	unsigned short		len;		/* Amount of data in buffer */
	unsigned short		space;		/* Remaining data space */
	unsigned short		offset;		/* Offset of fill point */
	unsigned short		crypto_header;	/* Size of crypto header */
	unsigned short		sec_header;	/* Size of security header */
	unsigned short		pkt_len;	/* Size of packet content */
	unsigned short		alloc_size;	/* Amount of bufferage allocated */
	unsigned int		flags;
@@ -1339,6 +1350,7 @@ int rxrpc_sendmsg_oob(struct rxrpc_sock *rx, struct msghdr *msg, size_t len);
/*
 * output.c
 */
ssize_t do_udp_sendmsg(struct socket *socket, struct msghdr *msg, size_t len);
void rxrpc_send_ACK(struct rxrpc_call *call, u8 ack_reason,
		    rxrpc_serial_t serial, enum rxrpc_propose_ack_trace why);
void rxrpc_send_probe_for_pmtud(struct rxrpc_call *call);
@@ -1411,6 +1423,11 @@ void rxrpc_call_add_rtt(struct rxrpc_call *call, enum rxrpc_rtt_rx_trace why,
ktime_t rxrpc_get_rto_backoff(struct rxrpc_call *call, bool retrans);
void rxrpc_call_init_rtt(struct rxrpc_call *call);

/*
 * rxgk.c
 */
extern const struct rxrpc_security rxgk_yfs;

/*
 * rxkad.c
 */
Loading