xref: /freebsd/crypto/krb5/src/lib/crypto/krb/crypto_int.h (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/crypto/krb/crypto_int.h - Master libk5crypto internal header */
3 /*
4  * Copyright (C) 2011 by the Massachusetts Institute of Technology.
5  * All rights reserved.
6  *
7  * Export of this software from the United States of America may
8  *   require a specific license from the United States Government.
9  *   It is the responsibility of any person or organization contemplating
10  *   export to obtain such a license before exporting.
11  *
12  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13  * distribute this software and its documentation for any purpose and
14  * without fee is hereby granted, provided that the above copyright
15  * notice appear in all copies and that both that copyright notice and
16  * this permission notice appear in supporting documentation, and that
17  * the name of M.I.T. not be used in advertising or publicity pertaining
18  * to distribution of the software without specific, written prior
19  * permission.  Furthermore if you modify this software you must label
20  * your software as modified software and not distribute it in such a
21  * fashion that it might be confused with the original M.I.T. software.
22  * M.I.T. makes no representations about the suitability of
23  * this software for any purpose.  It is provided "as is" without express
24  * or implied warranty.
25  */
26 
27 /* This header is the entry point for libk5crypto sources, and also documents
28  * requirements for crypto modules. */
29 
30 #ifndef CRYPTO_INT_H
31 #define CRYPTO_INT_H
32 
33 #include <k5-int.h>
34 
35 #if defined(CRYPTO_OPENSSL)
36 
37 #include <openssl/opensslv.h>
38 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
39 /*
40  * OpenSSL 3.0 relegates MD4 and RC4 to the legacy provider, which must be
41  * explicitly loaded into a library context.  Performing this loading within a
42  * library carries complications, so use the built-in implementations of these
43  * primitives instead.  OpenSSL 3.0 also deprecates DES_set_odd_parity() with
44  * no replacement.
45  *
46  * OpenSSL 3.0 adds KDF implementations matching the ones we use to derive
47  * encryption and authentication keys from protocol keys.  It also adds
48  * the EVP_MAC interface which can be used for CMAC.  (We could use the CMAC
49  * interface with OpenSSL 1.1 but currently do not.)
50  */
51 #define K5_BUILTIN_DES_KEY_PARITY
52 #define K5_BUILTIN_MD4
53 #define K5_BUILTIN_RC4
54 #define K5_OPENSSL_KDF
55 #define K5_OPENSSL_CMAC
56 #else
57 #define K5_OPENSSL_DES_KEY_PARITY
58 #define K5_OPENSSL_MD4
59 #define K5_OPENSSL_RC4
60 #define K5_BUILTIN_KDF
61 #define K5_BUILTIN_CMAC
62 #endif
63 
64 #define K5_OPENSSL_AES
65 #define K5_OPENSSL_CAMELLIA
66 #define K5_OPENSSL_DES
67 #define K5_OPENSSL_HMAC
68 #define K5_OPENSSL_MD5
69 #define K5_OPENSSL_PBKDF2
70 #define K5_OPENSSL_SHA1
71 #define K5_OPENSSL_SHA2
72 
73 #else
74 
75 #define K5_BUILTIN_AES
76 #define K5_BUILTIN_CAMELLIA
77 #define K5_BUILTIN_CMAC
78 #define K5_BUILTIN_DES
79 #define K5_BUILTIN_DES_KEY_PARITY
80 #define K5_BUILTIN_HMAC
81 #define K5_BUILTIN_KDF
82 #define K5_BUILTIN_MD4
83 #define K5_BUILTIN_MD5
84 #define K5_BUILTIN_PBKDF2
85 #define K5_BUILTIN_RC4
86 #define K5_BUILTIN_SHA1
87 #define K5_BUILTIN_SHA2
88 
89 #endif
90 
91 /* Enc providers and hash providers specify well-known ciphers and hashes to be
92  * implemented by the crypto module. */
93 
94 struct krb5_enc_provider {
95     /* keybytes is the input size to make_key;
96        keylength is the output size */
97     size_t block_size, keybytes, keylength;
98 
99     krb5_error_code (*encrypt)(krb5_key key, const krb5_data *cipher_state,
100                                krb5_crypto_iov *data, size_t num_data);
101 
102     krb5_error_code (*decrypt)(krb5_key key, const krb5_data *cipher_state,
103                                krb5_crypto_iov *data, size_t num_data);
104 
105     /* May be NULL if the cipher is not used for a cbc-mac checksum. */
106     krb5_error_code (*cbc_mac)(krb5_key key, const krb5_crypto_iov *data,
107                                size_t num_data, const krb5_data *ivec,
108                                krb5_data *output);
109 
110     krb5_error_code (*init_state)(const krb5_keyblock *key,
111                                   krb5_keyusage keyusage,
112                                   krb5_data *out_state);
113     void (*free_state)(krb5_data *state);
114 
115     /* May be NULL if there is no key-derived data cached.  */
116     void (*key_cleanup)(krb5_key key);
117 };
118 
119 struct krb5_hash_provider {
120     char hash_name[8];
121     size_t hashsize, blocksize;
122 
123     krb5_error_code (*hash)(const krb5_crypto_iov *data, size_t num_data,
124                             krb5_data *output);
125 };
126 
127 /*** RFC 3961 enctypes table ***/
128 
129 #define MAX_ETYPE_ALIASES 2
130 
131 struct krb5_keytypes;
132 
133 typedef unsigned int (*crypto_length_func)(const struct krb5_keytypes *ktp,
134                                            krb5_cryptotype type);
135 
136 typedef krb5_error_code (*crypt_func)(const struct krb5_keytypes *ktp,
137                                       krb5_key key, krb5_keyusage keyusage,
138                                       const krb5_data *ivec,
139                                       krb5_crypto_iov *data, size_t num_data);
140 
141 typedef krb5_error_code (*str2key_func)(const struct krb5_keytypes *ktp,
142                                         const krb5_data *string,
143                                         const krb5_data *salt,
144                                         const krb5_data *parm,
145                                         krb5_keyblock *key);
146 
147 typedef krb5_error_code (*rand2key_func)(const krb5_data *randombits,
148                                          krb5_keyblock *key);
149 
150 typedef krb5_error_code (*prf_func)(const struct krb5_keytypes *ktp,
151                                     krb5_key key,
152                                     const krb5_data *in, krb5_data *out);
153 
154 struct krb5_keytypes {
155     krb5_enctype etype;
156     char *name;
157     char *aliases[MAX_ETYPE_ALIASES];
158     char *out_string;
159     const struct krb5_enc_provider *enc;
160     const struct krb5_hash_provider *hash;
161     size_t prf_length;
162     crypto_length_func crypto_length;
163     crypt_func encrypt;
164     crypt_func decrypt;
165     str2key_func str2key;
166     rand2key_func rand2key;
167     prf_func prf;
168     krb5_cksumtype required_ctype;
169     krb5_flags flags;
170     unsigned int ssf;
171 };
172 
173 /*
174  * "Weak" means the enctype is believed to be vulnerable to practical attacks,
175  * and will be disabled unless allow_weak_crypto is set to true.  "Deprecated"
176  * means the enctype has been deprecated by the IETF, and affects display and
177  * logging.
178  */
179 #define ETYPE_WEAK (1 << 0)
180 #define ETYPE_DEPRECATED (1 << 1)
181 
182 extern const struct krb5_keytypes krb5int_enctypes_list[];
183 extern const int krb5int_enctypes_length;
184 
185 /*** RFC 3961 checksum types table ***/
186 
187 struct krb5_cksumtypes;
188 
189 /*
190  * Compute a checksum over the header, data, padding, and sign-only fields of
191  * the iov array data (of size num_data).  The output buffer will already be
192  * allocated with ctp->compute_size bytes available; the handler just needs to
193  * fill in the contents.  If ctp->enc is not NULL, the handler can assume that
194  * key is a valid-length key of an enctype which uses that enc provider.
195  */
196 typedef krb5_error_code (*checksum_func)(const struct krb5_cksumtypes *ctp,
197                                          krb5_key key, krb5_keyusage usage,
198                                          const krb5_crypto_iov *data,
199                                          size_t num_data,
200                                          krb5_data *output);
201 
202 /*
203  * Verify a checksum over the header, data, padding, and sign-only fields of
204  * the iov array data (of size num_data), and store the boolean result in
205  * *valid.  The handler can assume that hash has length ctp->output_size.  If
206  * ctp->enc is not NULL, the handler can assume that key a valid-length key of
207  * an enctype which uses that enc provider.
208  */
209 typedef krb5_error_code (*verify_func)(const struct krb5_cksumtypes *ctp,
210                                        krb5_key key, krb5_keyusage usage,
211                                        const krb5_crypto_iov *data,
212                                        size_t num_data,
213                                        const krb5_data *input,
214                                        krb5_boolean *valid);
215 
216 struct krb5_cksumtypes {
217     krb5_cksumtype ctype;
218     char *name;
219     char *aliases[2];
220     char *out_string;
221     const struct krb5_enc_provider *enc;
222     const struct krb5_hash_provider *hash;
223     checksum_func checksum;
224     verify_func verify;         /* NULL means recompute checksum and compare */
225     unsigned int compute_size;  /* Allocation size for checksum computation */
226     unsigned int output_size;   /* Possibly truncated output size */
227     krb5_flags flags;
228 };
229 
230 #define CKSUM_UNKEYED          0x0001
231 #define CKSUM_NOT_COLL_PROOF   0x0002
232 
233 extern const struct krb5_cksumtypes krb5int_cksumtypes_list[];
234 extern const size_t krb5int_cksumtypes_length;
235 
236 /*** Prototypes for enctype table functions ***/
237 
238 /* Length */
239 unsigned int krb5int_raw_crypto_length(const struct krb5_keytypes *ktp,
240                                        krb5_cryptotype type);
241 unsigned int krb5int_arcfour_crypto_length(const struct krb5_keytypes *ktp,
242                                            krb5_cryptotype type);
243 unsigned int krb5int_dk_crypto_length(const struct krb5_keytypes *ktp,
244                                       krb5_cryptotype type);
245 unsigned int krb5int_aes_crypto_length(const struct krb5_keytypes *ktp,
246                                        krb5_cryptotype type);
247 unsigned int krb5int_camellia_crypto_length(const struct krb5_keytypes *ktp,
248                                             krb5_cryptotype type);
249 unsigned int krb5int_aes2_crypto_length(const struct krb5_keytypes *ktp,
250                                         krb5_cryptotype type);
251 
252 /* Encrypt */
253 krb5_error_code krb5int_raw_encrypt(const struct krb5_keytypes *ktp,
254                                     krb5_key key, krb5_keyusage usage,
255                                     const krb5_data *ivec,
256                                     krb5_crypto_iov *data, size_t num_data);
257 krb5_error_code krb5int_arcfour_encrypt(const struct krb5_keytypes *ktp,
258                                         krb5_key key, krb5_keyusage usage,
259                                         const krb5_data *ivec,
260                                         krb5_crypto_iov *data,
261                                         size_t num_data);
262 krb5_error_code krb5int_dk_encrypt(const struct krb5_keytypes *ktp,
263                                    krb5_key key, krb5_keyusage usage,
264                                    const krb5_data *ivec,
265                                    krb5_crypto_iov *data, size_t num_data);
266 krb5_error_code krb5int_dk_cmac_encrypt(const struct krb5_keytypes *ktp,
267                                         krb5_key key, krb5_keyusage usage,
268                                         const krb5_data *ivec,
269                                         krb5_crypto_iov *data,
270                                         size_t num_data);
271 krb5_error_code krb5int_etm_encrypt(const struct krb5_keytypes *ktp,
272                                     krb5_key key, krb5_keyusage usage,
273                                     const krb5_data *ivec,
274                                     krb5_crypto_iov *data, size_t num_data);
275 
276 /* Decrypt */
277 krb5_error_code krb5int_raw_decrypt(const struct krb5_keytypes *ktp,
278                                     krb5_key key, krb5_keyusage usage,
279                                     const krb5_data *ivec,
280                                     krb5_crypto_iov *data, size_t num_data);
281 krb5_error_code krb5int_arcfour_decrypt(const struct krb5_keytypes *ktp,
282                                         krb5_key key, krb5_keyusage usage,
283                                         const krb5_data *ivec,
284                                         krb5_crypto_iov *data,
285                                         size_t num_data);
286 krb5_error_code krb5int_dk_decrypt(const struct krb5_keytypes *ktp,
287                                    krb5_key key, krb5_keyusage usage,
288                                    const krb5_data *ivec,
289                                    krb5_crypto_iov *data, size_t num_data);
290 krb5_error_code krb5int_dk_cmac_decrypt(const struct krb5_keytypes *ktp,
291                                         krb5_key key, krb5_keyusage usage,
292                                         const krb5_data *ivec,
293                                         krb5_crypto_iov *data,
294                                         size_t num_data);
295 krb5_error_code krb5int_etm_decrypt(const struct krb5_keytypes *ktp,
296                                     krb5_key key, krb5_keyusage usage,
297                                     const krb5_data *ivec,
298                                     krb5_crypto_iov *data, size_t num_data);
299 
300 /* String to key */
301 krb5_error_code krb5int_des_string_to_key(const struct krb5_keytypes *ktp,
302                                           const krb5_data *string,
303                                           const krb5_data *salt,
304                                           const krb5_data *params,
305                                           krb5_keyblock *key);
306 krb5_error_code krb5int_arcfour_string_to_key(const struct krb5_keytypes *ktp,
307                                               const krb5_data *string,
308                                               const krb5_data *salt,
309                                               const krb5_data *params,
310                                               krb5_keyblock *key);
311 krb5_error_code krb5int_dk_string_to_key(const struct krb5_keytypes *enc,
312                                          const krb5_data *string,
313                                          const krb5_data *salt,
314                                          const krb5_data *params,
315                                          krb5_keyblock *key);
316 krb5_error_code krb5int_aes_string_to_key(const struct krb5_keytypes *enc,
317                                           const krb5_data *string,
318                                           const krb5_data *salt,
319                                           const krb5_data *params,
320                                           krb5_keyblock *key);
321 krb5_error_code krb5int_camellia_string_to_key(const struct krb5_keytypes *enc,
322                                                const krb5_data *string,
323                                                const krb5_data *salt,
324                                                const krb5_data *params,
325                                                krb5_keyblock *key);
326 krb5_error_code krb5int_aes2_string_to_key(const struct krb5_keytypes *enc,
327                                            const krb5_data *string,
328                                            const krb5_data *salt,
329                                            const krb5_data *params,
330                                            krb5_keyblock *key);
331 
332 /* Random to key */
333 krb5_error_code k5_rand2key_direct(const krb5_data *randombits,
334                                    krb5_keyblock *keyblock);
335 krb5_error_code k5_rand2key_des3(const krb5_data *randombits,
336                                  krb5_keyblock *keyblock);
337 
338 /* Pseudo-random function */
339 krb5_error_code krb5int_des_prf(const struct krb5_keytypes *ktp,
340                                 krb5_key key, const krb5_data *in,
341                                 krb5_data *out);
342 krb5_error_code krb5int_arcfour_prf(const struct krb5_keytypes *ktp,
343                                     krb5_key key, const krb5_data *in,
344                                     krb5_data *out);
345 krb5_error_code krb5int_dk_prf(const struct krb5_keytypes *ktp, krb5_key key,
346                                const krb5_data *in, krb5_data *out);
347 krb5_error_code krb5int_dk_cmac_prf(const struct krb5_keytypes *ktp,
348                                     krb5_key key, const krb5_data *in,
349                                     krb5_data *out);
350 krb5_error_code krb5int_aes2_prf(const struct krb5_keytypes *ktp, krb5_key key,
351                                  const krb5_data *in, krb5_data *out);
352 
353 /*** Prototypes for cksumtype handler functions ***/
354 
355 krb5_error_code krb5int_unkeyed_checksum(const struct krb5_cksumtypes *ctp,
356                                          krb5_key key, krb5_keyusage usage,
357                                          const krb5_crypto_iov *data,
358                                          size_t num_data,
359                                          krb5_data *output);
360 krb5_error_code krb5int_hmacmd5_checksum(const struct krb5_cksumtypes *ctp,
361                                          krb5_key key, krb5_keyusage usage,
362                                          const krb5_crypto_iov *data,
363                                          size_t num_data,
364                                          krb5_data *output);
365 krb5_error_code krb5int_dk_checksum(const struct krb5_cksumtypes *ctp,
366                                     krb5_key key, krb5_keyusage usage,
367                                     const krb5_crypto_iov *data,
368                                     size_t num_data, krb5_data *output);
369 krb5_error_code krb5int_dk_cmac_checksum(const struct krb5_cksumtypes *ctp,
370                                          krb5_key key, krb5_keyusage usage,
371                                          const krb5_crypto_iov *data,
372                                          size_t num_data, krb5_data *output);
373 krb5_error_code krb5int_etm_checksum(const struct krb5_cksumtypes *ctp,
374                                      krb5_key key, krb5_keyusage usage,
375                                      const krb5_crypto_iov *data,
376                                      size_t num_data, krb5_data *output);
377 
378 /*** Key derivation functions ***/
379 
380 enum deriv_alg {
381     DERIVE_RFC3961,             /* RFC 3961 section 5.1 */
382     DERIVE_SP800_108_CMAC,      /* NIST SP 800-108 with CMAC as PRF */
383     DERIVE_SP800_108_HMAC       /* NIST SP 800-108 with HMAC as PRF */
384 };
385 
386 krb5_error_code krb5int_derive_keyblock(const struct krb5_enc_provider *enc,
387                                         const struct krb5_hash_provider *hash,
388                                         krb5_key inkey, krb5_keyblock *outkey,
389                                         const krb5_data *in_constant,
390                                         enum deriv_alg alg);
391 krb5_error_code krb5int_derive_key(const struct krb5_enc_provider *enc,
392                                    const struct krb5_hash_provider *hash,
393                                    krb5_key inkey, krb5_key *outkey,
394                                    const krb5_data *in_constant,
395                                    enum deriv_alg alg);
396 krb5_error_code krb5int_derive_random(const struct krb5_enc_provider *enc,
397                                       const struct krb5_hash_provider *hash,
398                                       krb5_key inkey, krb5_data *outrnd,
399                                       const krb5_data *in_constant,
400                                       enum deriv_alg alg);
401 
402 /*** Miscellaneous prototypes ***/
403 
404 /* nfold algorithm from RFC 3961 */
405 void krb5int_nfold(unsigned int inbits, const unsigned char *in,
406                    unsigned int outbits, unsigned char *out);
407 
408 /* Translate an RFC 3961 key usage to a Microsoft RC4 usage. */
409 krb5_keyusage krb5int_arcfour_translate_usage(krb5_keyusage usage);
410 
411 /* Ensure library initialization has occurred. */
412 int krb5int_crypto_init(void);
413 
414 /* DES default state initialization handler (used by module enc providers). */
415 krb5_error_code krb5int_des_init_state(const krb5_keyblock *key,
416                                        krb5_keyusage keyusage,
417                                        krb5_data *state_out);
418 
419 /* Default state cleanup handler (used by module enc providers). */
420 void krb5int_default_free_state(krb5_data *state);
421 
422 /*** Input/output vector processing declarations **/
423 
424 #define ENCRYPT_CONF_IOV(_iov)  ((_iov)->flags == KRB5_CRYPTO_TYPE_HEADER)
425 
426 #define ENCRYPT_DATA_IOV(_iov)  ((_iov)->flags == KRB5_CRYPTO_TYPE_DATA || \
427                                  (_iov)->flags == KRB5_CRYPTO_TYPE_PADDING)
428 
429 #define ENCRYPT_IOV(_iov)       (ENCRYPT_CONF_IOV(_iov) || ENCRYPT_DATA_IOV(_iov))
430 
431 #define SIGN_IOV(_iov)          (ENCRYPT_IOV(_iov) ||                   \
432                                  (_iov)->flags == KRB5_CRYPTO_TYPE_SIGN_ONLY )
433 
434 struct iov_cursor {
435     const krb5_crypto_iov *iov; /* iov array we are iterating over */
436     size_t iov_count;           /* size of iov array */
437     size_t block_size;          /* size of blocks we will be obtaining */
438     krb5_boolean signing;       /* should we process SIGN_ONLY blocks */
439     size_t in_iov;              /* read index into iov array */
440     size_t in_pos;              /* read index into iov contents */
441     size_t out_iov;             /* write index into iov array */
442     size_t out_pos;             /* write index into iov contents */
443 };
444 
445 krb5_crypto_iov *krb5int_c_locate_iov(krb5_crypto_iov *data, size_t num_data,
446                                       krb5_cryptotype type);
447 
448 krb5_error_code krb5int_c_iov_decrypt_stream(const struct krb5_keytypes *ktp,
449                                              krb5_key key,
450                                              krb5_keyusage keyusage,
451                                              const krb5_data *ivec,
452                                              krb5_crypto_iov *data,
453                                              size_t num_data);
454 
455 unsigned int krb5int_c_padding_length(const struct krb5_keytypes *ktp,
456                                       size_t data_length);
457 
458 void k5_iov_cursor_init(struct iov_cursor *cursor, const krb5_crypto_iov *iov,
459                         size_t count, size_t block_size, krb5_boolean signing);
460 
461 krb5_boolean k5_iov_cursor_get(struct iov_cursor *cursor,
462                                unsigned char *block);
463 
464 void k5_iov_cursor_put(struct iov_cursor *cursor, unsigned char *block);
465 
466 /*** Crypto module declarations ***/
467 
468 /* Modules must implement the k5_sha256() function prototyped in k5-int.h. */
469 
470 /* Modules must implement the following enc_providers and hash_providers: */
471 extern const struct krb5_enc_provider krb5int_enc_des3;
472 extern const struct krb5_enc_provider krb5int_enc_arcfour;
473 extern const struct krb5_enc_provider krb5int_enc_aes128;
474 extern const struct krb5_enc_provider krb5int_enc_aes256;
475 extern const struct krb5_enc_provider krb5int_enc_aes128_ctr;
476 extern const struct krb5_enc_provider krb5int_enc_aes256_ctr;
477 extern const struct krb5_enc_provider krb5int_enc_camellia128;
478 extern const struct krb5_enc_provider krb5int_enc_camellia256;
479 
480 extern const struct krb5_hash_provider krb5int_hash_md4;
481 extern const struct krb5_hash_provider krb5int_hash_md5;
482 extern const struct krb5_hash_provider krb5int_hash_sha1;
483 extern const struct krb5_hash_provider krb5int_hash_sha256;
484 extern const struct krb5_hash_provider krb5int_hash_sha384;
485 
486 /* Modules must implement the following functions. */
487 
488 /* Set the parity bits to the correct values in keybits. */
489 void k5_des_fixup_key_parity(unsigned char *keybits);
490 
491 /* Compute an HMAC using the provided hash function, key, and data, storing the
492  * result into output (caller-allocated). */
493 krb5_error_code krb5int_hmac(const struct krb5_hash_provider *hash,
494                              krb5_key key, const krb5_crypto_iov *data,
495                              size_t num_data, krb5_data *output);
496 
497 /* Compute a CMAC checksum over data. */
498 krb5_error_code krb5int_cmac_checksum(const struct krb5_enc_provider *enc,
499                                       krb5_key key,
500                                       const krb5_crypto_iov *data,
501                                       size_t num_data, krb5_data *output);
502 
503 /* As above, using a keyblock as the key input. */
504 krb5_error_code krb5int_hmac_keyblock(const struct krb5_hash_provider *hash,
505                                       const krb5_keyblock *keyblock,
506                                       const krb5_crypto_iov *data,
507                                       size_t num_data, krb5_data *output);
508 
509 /*
510  * Compute the PBKDF2 (see RFC 2898) of password and salt, with the specified
511  * count, using HMAC with the specified hash as the pseudo-random function,
512  * storing the result into out (caller-allocated).
513  */
514 krb5_error_code krb5int_pbkdf2_hmac(const struct krb5_hash_provider *hash,
515                                     const krb5_data *out, unsigned long count,
516                                     const krb5_data *password,
517                                     const krb5_data *salt);
518 
519 /*
520  * Compute the NIST SP800-108 KDF in counter mode (section 5.1) with the
521  * following parameters:
522  *   - HMAC (with hash as the hash provider) is the PRF.
523  *   - A block counter of four bytes is used.
524  *   - Four bytes are used to encode the output length in the PRF input.
525  *
526  * There are no uses requiring more than a single PRF invocation.
527  */
528 krb5_error_code
529 k5_sp800_108_counter_hmac(const struct krb5_hash_provider *hash,
530                           krb5_key key, const krb5_data *label,
531                           const krb5_data *context, krb5_data *rnd_out);
532 
533 /*
534  * Compute the NIST SP800-108 KDF in feedback mode (section 5.2) with the
535  * following parameters:
536  *   - CMAC (with enc as the enc provider) is the PRF.
537  *   - A block counter of four bytes is used.
538  *   - Label is the key derivation constant.
539  *   - Context is empty.
540  *   - Four bytes are used to encode the output length in the PRF input.
541  */
542 krb5_error_code
543 k5_sp800_108_feedback_cmac(const struct krb5_enc_provider *enc, krb5_key key,
544                            const krb5_data *label, krb5_data *rnd_out);
545 
546 /* Compute the RFC 3961 section 5.1 KDF (which uses n-fold) with enc as E,
547  * inkey as Key, and in_constant as Constant. */
548 krb5_error_code
549 k5_derive_random_rfc3961(const struct krb5_enc_provider *enc, krb5_key key,
550                          const krb5_data *constant, krb5_data *rnd_out);
551 
552 /* The following are used by test programs and are just handler functions from
553  * the AES and Camellia enc providers. */
554 krb5_error_code krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec,
555                                     krb5_crypto_iov *data, size_t num_data);
556 krb5_error_code krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec,
557                                     krb5_crypto_iov *data, size_t num_data);
558 krb5_error_code krb5int_camellia_encrypt(krb5_key key, const krb5_data *ivec,
559                                          krb5_crypto_iov *data,
560                                          size_t num_data);
561 
562 /*** Inline helper functions ***/
563 
564 /* Find an enctype by number in the enctypes table. */
565 static inline const struct krb5_keytypes *
find_enctype(krb5_enctype enctype)566 find_enctype(krb5_enctype enctype)
567 {
568     int i;
569 
570     for (i = 0; i < krb5int_enctypes_length; i++) {
571         if (krb5int_enctypes_list[i].etype == enctype)
572             break;
573     }
574 
575     if (i == krb5int_enctypes_length)
576         return NULL;
577     return &krb5int_enctypes_list[i];
578 }
579 
580 /* Find a checksum type by number in the cksumtypes table. */
581 static inline const struct krb5_cksumtypes *
find_cksumtype(krb5_cksumtype ctype)582 find_cksumtype(krb5_cksumtype ctype)
583 {
584     size_t i;
585 
586     for (i = 0; i < krb5int_cksumtypes_length; i++) {
587         if (krb5int_cksumtypes_list[i].ctype == ctype)
588             break;
589     }
590 
591     if (i == krb5int_cksumtypes_length)
592         return NULL;
593     return &krb5int_cksumtypes_list[i];
594 }
595 
596 /* Verify that a key is appropriate for a checksum type. */
597 static inline krb5_error_code
verify_key(const struct krb5_cksumtypes * ctp,krb5_key key)598 verify_key(const struct krb5_cksumtypes *ctp, krb5_key key)
599 {
600     const struct krb5_keytypes *ktp;
601 
602     ktp = key ? find_enctype(key->keyblock.enctype) : NULL;
603     if (ctp->enc != NULL && (!ktp || ktp->enc != ctp->enc))
604         return KRB5_BAD_ENCTYPE;
605     if (key && (!ktp || key->keyblock.length != ktp->enc->keylength))
606         return KRB5_BAD_KEYSIZE;
607     return 0;
608 }
609 
610 /* Encrypt one block of plaintext in place, for block ciphers. */
611 static inline krb5_error_code
encrypt_block(const struct krb5_enc_provider * enc,krb5_key key,krb5_data * block)612 encrypt_block(const struct krb5_enc_provider *enc, krb5_key key,
613               krb5_data *block)
614 {
615     krb5_crypto_iov iov;
616 
617     /* Verify that this is a block cipher and block is the right length. */
618     if (block->length != enc->block_size || enc->block_size == 1)
619         return EINVAL;
620     iov.flags = KRB5_CRYPTO_TYPE_DATA;
621     iov.data = *block;
622     if (enc->cbc_mac != NULL)   /* One-block cbc-mac with no ivec. */
623         return enc->cbc_mac(key, &iov, 1, NULL, block);
624     else                        /* Assume cbc-mode encrypt. */
625         return enc->encrypt(key, 0, &iov, 1);
626 }
627 
628 /* Return the total length of the to-be-signed or to-be-encrypted buffers in an
629  * iov chain. */
630 static inline size_t
iov_total_length(const krb5_crypto_iov * data,size_t num_data,krb5_boolean signing)631 iov_total_length(const krb5_crypto_iov *data, size_t num_data,
632                  krb5_boolean signing)
633 {
634     size_t i, total = 0;
635 
636     for (i = 0; i < num_data; i++) {
637         if (signing ? SIGN_IOV(&data[i]) : ENCRYPT_IOV(&data[i]))
638             total += data[i].data.length;
639     }
640     return total;
641 }
642 
643 /*
644  * Return the number of contiguous blocks available within the current input
645  * IOV of the cursor c, so that the caller can do in-place encryption.
646  * Do not call if c might be exhausted.
647  */
648 static inline size_t
iov_cursor_contig_blocks(struct iov_cursor * c)649 iov_cursor_contig_blocks(struct iov_cursor *c)
650 {
651     return (c->iov[c->in_iov].data.length - c->in_pos) / c->block_size;
652 }
653 
654 /* Return the current input pointer within the cursor c.  Do not call if c
655  * might be exhausted. */
656 static inline unsigned char *
iov_cursor_ptr(struct iov_cursor * c)657 iov_cursor_ptr(struct iov_cursor *c)
658 {
659     return (unsigned char *)&c->iov[c->in_iov].data.data[c->in_pos];
660 }
661 
662 /*
663  * Advance the input and output pointers of c by nblocks blocks.  nblocks must
664  * not be greater than the return value of iov_cursor_contig_blocks, and the
665  * input and output positions must be identical.
666  */
667 static inline void
iov_cursor_advance(struct iov_cursor * c,size_t nblocks)668 iov_cursor_advance(struct iov_cursor *c, size_t nblocks)
669 {
670     c->in_pos += nblocks * c->block_size;
671     c->out_pos += nblocks * c->block_size;
672 }
673 
674 #endif /* CRYPTO_INT_H */
675