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