1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /* Kerberos5 crypto internals
3  *
4  * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
5  * Written by David Howells (dhowells@redhat.com)
6  */
7 
8 #include <linux/scatterlist.h>
9 #include <crypto/krb5.h>
10 #include <crypto/hash.h>
11 #include <crypto/skcipher.h>
12 
13 /*
14  * Profile used for key derivation and encryption.
15  */
16 struct krb5_crypto_profile {
17 	 /* Pseudo-random function */
18 	int (*calc_PRF)(const struct krb5_enctype *krb5,
19 			const struct krb5_buffer *protocol_key,
20 			const struct krb5_buffer *octet_string,
21 			struct krb5_buffer *result,
22 			gfp_t gfp);
23 
24 	/* Checksum key derivation */
25 	int (*calc_Kc)(const struct krb5_enctype *krb5,
26 		       const struct krb5_buffer *TK,
27 		       const struct krb5_buffer *usage_constant,
28 		       struct krb5_buffer *Kc,
29 		       gfp_t gfp);
30 
31 	/* Encryption key derivation */
32 	int (*calc_Ke)(const struct krb5_enctype *krb5,
33 		       const struct krb5_buffer *TK,
34 		       const struct krb5_buffer *usage_constant,
35 		       struct krb5_buffer *Ke,
36 		       gfp_t gfp);
37 
38 	 /* Integrity key derivation */
39 	int (*calc_Ki)(const struct krb5_enctype *krb5,
40 		       const struct krb5_buffer *TK,
41 		       const struct krb5_buffer *usage_constant,
42 		       struct krb5_buffer *Ki,
43 		       gfp_t gfp);
44 
45 	/* Derive the keys needed for an encryption AEAD object. */
46 	int (*derive_encrypt_keys)(const struct krb5_enctype *krb5,
47 				   const struct krb5_buffer *TK,
48 				   unsigned int usage,
49 				   struct krb5_buffer *setkey,
50 				   gfp_t gfp);
51 
52 	/* Directly load the keys needed for an encryption AEAD object. */
53 	int (*load_encrypt_keys)(const struct krb5_enctype *krb5,
54 				 const struct krb5_buffer *Ke,
55 				 const struct krb5_buffer *Ki,
56 				 struct krb5_buffer *setkey,
57 				 gfp_t gfp);
58 
59 	/* Derive the key needed for a checksum hash object. */
60 	int (*derive_checksum_key)(const struct krb5_enctype *krb5,
61 				   const struct krb5_buffer *TK,
62 				   unsigned int usage,
63 				   struct krb5_buffer *setkey,
64 				   gfp_t gfp);
65 
66 	/* Directly load the keys needed for a checksum hash object. */
67 	int (*load_checksum_key)(const struct krb5_enctype *krb5,
68 				 const struct krb5_buffer *Kc,
69 				 struct krb5_buffer *setkey,
70 				 gfp_t gfp);
71 
72 	/* Encrypt data in-place, inserting confounder and checksum. */
73 	ssize_t (*encrypt)(const struct krb5_enctype *krb5,
74 			   struct crypto_aead *aead,
75 			   struct scatterlist *sg, unsigned int nr_sg,
76 			   size_t sg_len,
77 			   size_t data_offset, size_t data_len,
78 			   bool preconfounded);
79 
80 	/* Decrypt data in-place, removing confounder and checksum */
81 	int (*decrypt)(const struct krb5_enctype *krb5,
82 		       struct crypto_aead *aead,
83 		       struct scatterlist *sg, unsigned int nr_sg,
84 		       size_t *_offset, size_t *_len);
85 
86 	/* Generate a MIC on part of a packet, inserting the checksum */
87 	ssize_t (*get_mic)(const struct krb5_enctype *krb5,
88 			   struct crypto_shash *shash,
89 			   const struct krb5_buffer *metadata,
90 			   struct scatterlist *sg, unsigned int nr_sg,
91 			   size_t sg_len,
92 			   size_t data_offset, size_t data_len);
93 
94 	/* Verify the MIC on a piece of data, removing the checksum */
95 	int (*verify_mic)(const struct krb5_enctype *krb5,
96 			  struct crypto_shash *shash,
97 			  const struct krb5_buffer *metadata,
98 			  struct scatterlist *sg, unsigned int nr_sg,
99 			  size_t *_offset, size_t *_len);
100 };
101 
102 /*
103  * Crypto size/alignment rounding convenience macros.
104  */
105 #define crypto_roundup(X) ((unsigned int)round_up((X), CRYPTO_MINALIGN))
106 
107 #define krb5_aead_size(TFM) \
108 	crypto_roundup(sizeof(struct aead_request) + crypto_aead_reqsize(TFM))
109 #define krb5_aead_ivsize(TFM) \
110 	crypto_roundup(crypto_aead_ivsize(TFM))
111 #define krb5_shash_size(TFM) \
112 	crypto_roundup(sizeof(struct shash_desc) + crypto_shash_descsize(TFM))
113 #define krb5_digest_size(TFM) \
114 	crypto_roundup(crypto_shash_digestsize(TFM))
115 #define round16(x) (((x) + 15) & ~15)
116 
117 /*
118  * Self-testing data.
119  */
120 struct krb5_prf_test {
121 	u32 etype;
122 	const char *name, *key, *octet, *prf;
123 };
124 
125 struct krb5_key_test_one {
126 	u32 use;
127 	const char *key;
128 };
129 
130 struct krb5_key_test {
131 	u32 etype;
132 	const char *name, *key;
133 	struct krb5_key_test_one Kc, Ke, Ki;
134 };
135 
136 struct krb5_enc_test {
137 	u32 etype;
138 	u32 usage;
139 	const char *name, *plain, *conf, *K0, *Ke, *Ki, *ct;
140 };
141 
142 struct krb5_mic_test {
143 	u32 etype;
144 	u32 usage;
145 	const char *name, *plain, *K0, *Kc, *mic;
146 };
147 
148 /*
149  * krb5_api.c
150  */
151 struct crypto_aead *krb5_prepare_encryption(const struct krb5_enctype *krb5,
152 					    const struct krb5_buffer *keys,
153 					    gfp_t gfp);
154 struct crypto_shash *krb5_prepare_checksum(const struct krb5_enctype *krb5,
155 					   const struct krb5_buffer *Kc,
156 					   gfp_t gfp);
157 
158 /*
159  * krb5_kdf.c
160  */
161 int krb5_derive_Kc(const struct krb5_enctype *krb5, const struct krb5_buffer *TK,
162 		   u32 usage, struct krb5_buffer *key, gfp_t gfp);
163 int krb5_derive_Ke(const struct krb5_enctype *krb5, const struct krb5_buffer *TK,
164 		   u32 usage, struct krb5_buffer *key, gfp_t gfp);
165 int krb5_derive_Ki(const struct krb5_enctype *krb5, const struct krb5_buffer *TK,
166 		   u32 usage, struct krb5_buffer *key, gfp_t gfp);
167 
168 /*
169  * rfc3961_simplified.c
170  */
171 extern const struct krb5_crypto_profile rfc3961_simplified_profile;
172 
173 int crypto_shash_update_sg(struct shash_desc *desc, struct scatterlist *sg,
174 			   size_t offset, size_t len);
175 int authenc_derive_encrypt_keys(const struct krb5_enctype *krb5,
176 				const struct krb5_buffer *TK,
177 				unsigned int usage,
178 				struct krb5_buffer *setkey,
179 				gfp_t gfp);
180 int authenc_load_encrypt_keys(const struct krb5_enctype *krb5,
181 			      const struct krb5_buffer *Ke,
182 			      const struct krb5_buffer *Ki,
183 			      struct krb5_buffer *setkey,
184 			      gfp_t gfp);
185 int rfc3961_derive_checksum_key(const struct krb5_enctype *krb5,
186 				const struct krb5_buffer *TK,
187 				unsigned int usage,
188 				struct krb5_buffer *setkey,
189 				gfp_t gfp);
190 int rfc3961_load_checksum_key(const struct krb5_enctype *krb5,
191 			      const struct krb5_buffer *Kc,
192 			      struct krb5_buffer *setkey,
193 			      gfp_t gfp);
194 ssize_t krb5_aead_encrypt(const struct krb5_enctype *krb5,
195 			  struct crypto_aead *aead,
196 			  struct scatterlist *sg, unsigned int nr_sg, size_t sg_len,
197 			  size_t data_offset, size_t data_len,
198 			  bool preconfounded);
199 int krb5_aead_decrypt(const struct krb5_enctype *krb5,
200 		      struct crypto_aead *aead,
201 		      struct scatterlist *sg, unsigned int nr_sg,
202 		      size_t *_offset, size_t *_len);
203 ssize_t rfc3961_get_mic(const struct krb5_enctype *krb5,
204 			struct crypto_shash *shash,
205 			const struct krb5_buffer *metadata,
206 			struct scatterlist *sg, unsigned int nr_sg, size_t sg_len,
207 			size_t data_offset, size_t data_len);
208 int rfc3961_verify_mic(const struct krb5_enctype *krb5,
209 		       struct crypto_shash *shash,
210 		       const struct krb5_buffer *metadata,
211 		       struct scatterlist *sg, unsigned int nr_sg,
212 		       size_t *_offset, size_t *_len);
213 
214 /*
215  * rfc3962_aes.c
216  */
217 extern const struct krb5_enctype krb5_aes128_cts_hmac_sha1_96;
218 extern const struct krb5_enctype krb5_aes256_cts_hmac_sha1_96;
219 
220 /*
221  * rfc6803_camellia.c
222  */
223 extern const struct krb5_enctype krb5_camellia128_cts_cmac;
224 extern const struct krb5_enctype krb5_camellia256_cts_cmac;
225 
226 /*
227  * rfc8009_aes2.c
228  */
229 extern const struct krb5_enctype krb5_aes128_cts_hmac_sha256_128;
230 extern const struct krb5_enctype krb5_aes256_cts_hmac_sha384_192;
231 
232 /*
233  * selftest.c
234  */
235 #ifdef CONFIG_CRYPTO_KRB5_SELFTESTS
236 int krb5_selftest(void);
237 #else
krb5_selftest(void)238 static inline int krb5_selftest(void) { return 0; }
239 #endif
240 
241 /*
242  * selftest_data.c
243  */
244 extern const struct krb5_prf_test krb5_prf_tests[];
245 extern const struct krb5_key_test krb5_key_tests[];
246 extern const struct krb5_enc_test krb5_enc_tests[];
247 extern const struct krb5_mic_test krb5_mic_tests[];
248