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 */ 15 struct 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 */ 42 int 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); 45 int 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 */ 52 void rxgk_put(struct rxgk_context *gk); 53 struct 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); 57 int 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 */ 68 static inline 69 int 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 -EPROTO: 92 case -EBADMSG: 93 *_error_code = RXGK_SEALEDINCON; 94 break; 95 default: 96 break; 97 } 98 99 return ret; 100 } 101 102 /* 103 * Check the MIC on a region of an skbuff. The offset and length are updated 104 * to reflect the actual content of the secure region. 105 */ 106 static inline 107 int rxgk_verify_mic_skb(const struct krb5_enctype *krb5, 108 struct crypto_shash *shash, 109 const struct krb5_buffer *metadata, 110 struct sk_buff *skb, 111 unsigned int *_offset, unsigned int *_len, 112 u32 *_error_code) 113 { 114 struct scatterlist sg[16]; 115 size_t offset = 0, len = *_len; 116 int nr_sg, ret; 117 118 sg_init_table(sg, ARRAY_SIZE(sg)); 119 nr_sg = skb_to_sgvec(skb, sg, *_offset, len); 120 if (unlikely(nr_sg < 0)) 121 return nr_sg; 122 123 ret = crypto_krb5_verify_mic(krb5, shash, metadata, sg, nr_sg, 124 &offset, &len); 125 switch (ret) { 126 case 0: 127 *_offset += offset; 128 *_len = len; 129 break; 130 case -EPROTO: 131 case -EBADMSG: 132 *_error_code = RXGK_SEALEDINCON; 133 break; 134 default: 135 break; 136 } 137 138 return ret; 139 } 140