File Index
Files and directories
Sign in
FILE

rxgk_common.h

File preview with syntax highlighting.

linux-6.19.14/net/rxrpc/rxgk_common.h C
  1/* SPDX-License-Identifier: GPL-2.0-or-later */
  2/* Common bits for GSSAPI-based RxRPC security.
  3 *
  4 * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
  5 * Written by David Howells (dhowells@redhat.com)
  6 */
  7
  8#include <crypto/krb5.h>
  9#include <crypto/skcipher.h>
 10#include <crypto/hash.h>
 11
 12/*
 13 * Per-key number context.  This is replaced when the connection is rekeyed.
 14 */
 15struct rxgk_context {
 16	refcount_t		usage;
 17	unsigned int		key_number;	/* Rekeying number (goes in the rx header) */
 18	unsigned long		flags;
 19#define RXGK_TK_NEEDS_REKEY	0		/* Set if this needs rekeying */
 20	unsigned long		expiry;		/* Expiration time of this key */
 21	long long		bytes_remaining; /* Remaining Tx lifetime of this key */
 22	const struct krb5_enctype *krb5;	/* RxGK encryption type */
 23	const struct rxgk_key	*key;
 24
 25	/* We need up to 7 keys derived from the transport key, but we don't
 26	 * actually need the transport key.  Each key is derived by
 27	 * DK(TK,constant).
 28	 */
 29	struct crypto_aead	*tx_enc;	/* Transmission key */
 30	struct crypto_aead	*rx_enc;	/* Reception key */
 31	struct crypto_shash	*tx_Kc;		/* Transmission checksum key */
 32	struct crypto_shash	*rx_Kc;		/* Reception checksum key */
 33	struct crypto_aead	*resp_enc;	/* Response packet enc key */
 34};
 35
 36#define xdr_round_up(x) (round_up((x), sizeof(__be32)))
 37#define xdr_object_len(x) (4 + xdr_round_up(x))
 38
 39/*
 40 * rxgk_app.c
 41 */
 42int rxgk_yfs_decode_ticket(struct rxrpc_connection *conn, struct sk_buff *skb,
 43			   unsigned int ticket_offset, unsigned int ticket_len,
 44			   struct key **_key);
 45int rxgk_extract_token(struct rxrpc_connection *conn, struct sk_buff *skb,
 46		       unsigned int token_offset, unsigned int token_len,
 47		       struct key **_key);
 48
 49/*
 50 * rxgk_kdf.c
 51 */
 52void rxgk_put(struct rxgk_context *gk);
 53struct rxgk_context *rxgk_generate_transport_key(struct rxrpc_connection *conn,
 54						 const struct rxgk_key *key,
 55						 unsigned int key_number,
 56						 gfp_t gfp);
 57int rxgk_set_up_token_cipher(const struct krb5_buffer *server_key,
 58			     struct crypto_aead **token_key,
 59			     unsigned int enctype,
 60			     const struct krb5_enctype **_krb5,
 61			     gfp_t gfp);
 62
 63/*
 64 * Apply decryption and checksumming functions to part of an skbuff.  The
 65 * offset and length are updated to reflect the actual content of the encrypted
 66 * region.
 67 */
 68static inline
 69int rxgk_decrypt_skb(const struct krb5_enctype *krb5,
 70		     struct crypto_aead *aead,
 71		     struct sk_buff *skb,
 72		     unsigned int *_offset, unsigned int *_len,
 73		     int *_error_code)
 74{
 75	struct scatterlist sg[16];
 76	size_t offset = 0, len = *_len;
 77	int nr_sg, ret;
 78
 79	sg_init_table(sg, ARRAY_SIZE(sg));
 80	nr_sg = skb_to_sgvec(skb, sg, *_offset, len);
 81	if (unlikely(nr_sg < 0))
 82		return nr_sg;
 83
 84	ret = crypto_krb5_decrypt(krb5, aead, sg, nr_sg,
 85				  &offset, &len);
 86	switch (ret) {
 87	case 0:
 88		*_offset += offset;
 89		*_len = len;
 90		break;
 91	case -EBADMSG: /* Checksum mismatch. */
 92	case -EPROTO:
 93		*_error_code = RXGK_SEALEDINCON;
 94		break;
 95	case -EMSGSIZE:
 96		*_error_code = RXGK_PACKETSHORT;
 97		break;
 98	case -ENOPKG: /* Would prefer RXGK_BADETYPE, but not available for YFS. */
 99	default:
100		*_error_code = RXGK_INCONSISTENCY;
101		break;
102	}
103
104	return ret;
105}
106
107/*
108 * Check the MIC on a region of an skbuff.  The offset and length are updated
109 * to reflect the actual content of the secure region.
110 */
111static inline
112int rxgk_verify_mic_skb(const struct krb5_enctype *krb5,
113			struct crypto_shash *shash,
114			const struct krb5_buffer *metadata,
115			struct sk_buff *skb,
116			unsigned int *_offset, unsigned int *_len,
117			u32 *_error_code)
118{
119	struct scatterlist sg[16];
120	size_t offset = 0, len = *_len;
121	int nr_sg, ret;
122
123	sg_init_table(sg, ARRAY_SIZE(sg));
124	nr_sg = skb_to_sgvec(skb, sg, *_offset, len);
125	if (unlikely(nr_sg < 0))
126		return nr_sg;
127
128	ret = crypto_krb5_verify_mic(krb5, shash, metadata, sg, nr_sg,
129				     &offset, &len);
130	switch (ret) {
131	case 0:
132		*_offset += offset;
133		*_len = len;
134		break;
135	case -EBADMSG: /* Checksum mismatch */
136	case -EPROTO:
137		*_error_code = RXGK_SEALEDINCON;
138		break;
139	case -EMSGSIZE:
140		*_error_code = RXGK_PACKETSHORT;
141		break;
142	case -ENOPKG: /* Would prefer RXGK_BADETYPE, but not available for YFS. */
143	default:
144		*_error_code = RXGK_INCONSISTENCY;
145		break;
146	}
147
148	return ret;
149}
~/ Read-only file preview.