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