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 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