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 and PRNG modules. */
29
30 #ifndef CRYPTO_INT_H
31 #define CRYPTO_INT_H
32
33 #include <k5-int.h>
34
35 /* Enc providers and hash providers specify well-known ciphers and hashes to be
36 * implemented by the crypto module. */
37
38 struct krb5_enc_provider {
39 /* keybytes is the input size to make_key;
40 keylength is the output size */
41 size_t block_size, keybytes, keylength;
42
43 krb5_error_code (*encrypt)(krb5_key key, const krb5_data *cipher_state,
44 krb5_crypto_iov *data, size_t num_data);
45
46 krb5_error_code (*decrypt)(krb5_key key, const krb5_data *cipher_state,
47 krb5_crypto_iov *data, size_t num_data);
48
49 /* May be NULL if the cipher is not used for a cbc-mac checksum. */
50 krb5_error_code (*cbc_mac)(krb5_key key, const krb5_crypto_iov *data,
51 size_t num_data, const krb5_data *ivec,
52 krb5_data *output);
53
54 krb5_error_code (*init_state)(const krb5_keyblock *key,
55 krb5_keyusage keyusage,
56 krb5_data *out_state);
57 void (*free_state)(krb5_data *state);
58
59 /* May be NULL if there is no key-derived data cached. */
60 void (*key_cleanup)(krb5_key key);
61 };
62
63 struct krb5_hash_provider {
64 char hash_name[8];
65 size_t hashsize, blocksize;
66
67 krb5_error_code (*hash)(const krb5_crypto_iov *data, size_t num_data,
68 krb5_data *output);
69 };
70
71 /*** RFC 3961 enctypes table ***/
72
73 #define MAX_ETYPE_ALIASES 2
74
75 struct krb5_keytypes;
76
77 typedef unsigned int (*crypto_length_func)(const struct krb5_keytypes *ktp,
78 krb5_cryptotype type);
79
80 typedef krb5_error_code (*crypt_func)(const struct krb5_keytypes *ktp,
81 krb5_key key, krb5_keyusage keyusage,
82 const krb5_data *ivec,
83 krb5_crypto_iov *data, size_t num_data);
84
85 typedef krb5_error_code (*str2key_func)(const struct krb5_keytypes *ktp,
86 const krb5_data *string,
87 const krb5_data *salt,
88 const krb5_data *parm,
89 krb5_keyblock *key);
90
91 typedef krb5_error_code (*rand2key_func)(const krb5_data *randombits,
92 krb5_keyblock *key);
93
94 typedef krb5_error_code (*prf_func)(const struct krb5_keytypes *ktp,
95 krb5_key key,
96 const krb5_data *in, krb5_data *out);
97
98 struct krb5_keytypes {
99 krb5_enctype etype;
100 char *name;
101 char *aliases[MAX_ETYPE_ALIASES];
102 char *out_string;
103 const struct krb5_enc_provider *enc;
104 const struct krb5_hash_provider *hash;
105 size_t prf_length;
106 crypto_length_func crypto_length;
107 crypt_func encrypt;
108 crypt_func decrypt;
109 str2key_func str2key;
110 rand2key_func rand2key;
111 prf_func prf;
112 krb5_cksumtype required_ctype;
113 krb5_flags flags;
114 unsigned int ssf;
115 };
116
117 /*
118 * "Weak" means the enctype is believed to be vulnerable to practical attacks,
119 * and will be disabled unless allow_weak_crypto is set to true. "Deprecated"
120 * means the enctype has been deprecated by the IETF, and affects display and
121 * logging.
122 */
123 #define ETYPE_WEAK (1 << 0)
124 #define ETYPE_DEPRECATED (1 << 1)
125
126 extern const struct krb5_keytypes krb5int_enctypes_list[];
127 extern const int krb5int_enctypes_length;
128
129 /*** RFC 3961 checksum types table ***/
130
131 struct krb5_cksumtypes;
132
133 /*
134 * Compute a checksum over the header, data, padding, and sign-only fields of
135 * the iov array data (of size num_data). The output buffer will already be
136 * allocated with ctp->compute_size bytes available; the handler just needs to
137 * fill in the contents. If ctp->enc is not NULL, the handler can assume that
138 * key is a valid-length key of an enctype which uses that enc provider.
139 */
140 typedef krb5_error_code (*checksum_func)(const struct krb5_cksumtypes *ctp,
141 krb5_key key, krb5_keyusage usage,
142 const krb5_crypto_iov *data,
143 size_t num_data,
144 krb5_data *output);
145
146 /*
147 * Verify a checksum over the header, data, padding, and sign-only fields of
148 * the iov array data (of size num_data), and store the boolean result in
149 * *valid. The handler can assume that hash has length ctp->output_size. If
150 * ctp->enc is not NULL, the handler can assume that key a valid-length key of
151 * an enctype which uses that enc provider.
152 */
153 typedef krb5_error_code (*verify_func)(const struct krb5_cksumtypes *ctp,
154 krb5_key key, krb5_keyusage usage,
155 const krb5_crypto_iov *data,
156 size_t num_data,
157 const krb5_data *input,
158 krb5_boolean *valid);
159
160 struct krb5_cksumtypes {
161 krb5_cksumtype ctype;
162 char *name;
163 char *aliases[2];
164 char *out_string;
165 const struct krb5_enc_provider *enc;
166 const struct krb5_hash_provider *hash;
167 checksum_func checksum;
168 verify_func verify; /* NULL means recompute checksum and compare */
169 unsigned int compute_size; /* Allocation size for checksum computation */
170 unsigned int output_size; /* Possibly truncated output size */
171 krb5_flags flags;
172 };
173
174 #define CKSUM_UNKEYED 0x0001
175 #define CKSUM_NOT_COLL_PROOF 0x0002
176
177 extern const struct krb5_cksumtypes krb5int_cksumtypes_list[];
178 extern const size_t krb5int_cksumtypes_length;
179
180 /*** Prototypes for enctype table functions ***/
181
182 /* Length */
183 unsigned int krb5int_raw_crypto_length(const struct krb5_keytypes *ktp,
184 krb5_cryptotype type);
185 unsigned int krb5int_arcfour_crypto_length(const struct krb5_keytypes *ktp,
186 krb5_cryptotype type);
187 unsigned int krb5int_dk_crypto_length(const struct krb5_keytypes *ktp,
188 krb5_cryptotype type);
189 unsigned int krb5int_aes_crypto_length(const struct krb5_keytypes *ktp,
190 krb5_cryptotype type);
191 unsigned int krb5int_camellia_crypto_length(const struct krb5_keytypes *ktp,
192 krb5_cryptotype type);
193 unsigned int krb5int_aes2_crypto_length(const struct krb5_keytypes *ktp,
194 krb5_cryptotype type);
195
196 /* Encrypt */
197 krb5_error_code krb5int_raw_encrypt(const struct krb5_keytypes *ktp,
198 krb5_key key, krb5_keyusage usage,
199 const krb5_data *ivec,
200 krb5_crypto_iov *data, size_t num_data);
201 krb5_error_code krb5int_arcfour_encrypt(const struct krb5_keytypes *ktp,
202 krb5_key key, krb5_keyusage usage,
203 const krb5_data *ivec,
204 krb5_crypto_iov *data,
205 size_t num_data);
206 krb5_error_code krb5int_dk_encrypt(const struct krb5_keytypes *ktp,
207 krb5_key key, krb5_keyusage usage,
208 const krb5_data *ivec,
209 krb5_crypto_iov *data, size_t num_data);
210 krb5_error_code krb5int_dk_cmac_encrypt(const struct krb5_keytypes *ktp,
211 krb5_key key, krb5_keyusage usage,
212 const krb5_data *ivec,
213 krb5_crypto_iov *data,
214 size_t num_data);
215 krb5_error_code krb5int_etm_encrypt(const struct krb5_keytypes *ktp,
216 krb5_key key, krb5_keyusage usage,
217 const krb5_data *ivec,
218 krb5_crypto_iov *data, size_t num_data);
219
220 /* Decrypt */
221 krb5_error_code krb5int_raw_decrypt(const struct krb5_keytypes *ktp,
222 krb5_key key, krb5_keyusage usage,
223 const krb5_data *ivec,
224 krb5_crypto_iov *data, size_t num_data);
225 krb5_error_code krb5int_arcfour_decrypt(const struct krb5_keytypes *ktp,
226 krb5_key key, krb5_keyusage usage,
227 const krb5_data *ivec,
228 krb5_crypto_iov *data,
229 size_t num_data);
230 krb5_error_code krb5int_dk_decrypt(const struct krb5_keytypes *ktp,
231 krb5_key key, krb5_keyusage usage,
232 const krb5_data *ivec,
233 krb5_crypto_iov *data, size_t num_data);
234 krb5_error_code krb5int_dk_cmac_decrypt(const struct krb5_keytypes *ktp,
235 krb5_key key, krb5_keyusage usage,
236 const krb5_data *ivec,
237 krb5_crypto_iov *data,
238 size_t num_data);
239 krb5_error_code krb5int_etm_decrypt(const struct krb5_keytypes *ktp,
240 krb5_key key, krb5_keyusage usage,
241 const krb5_data *ivec,
242 krb5_crypto_iov *data, size_t num_data);
243
244 /* String to key */
245 krb5_error_code krb5int_des_string_to_key(const struct krb5_keytypes *ktp,
246 const krb5_data *string,
247 const krb5_data *salt,
248 const krb5_data *params,
249 krb5_keyblock *key);
250 krb5_error_code krb5int_arcfour_string_to_key(const struct krb5_keytypes *ktp,
251 const krb5_data *string,
252 const krb5_data *salt,
253 const krb5_data *params,
254 krb5_keyblock *key);
255 krb5_error_code krb5int_dk_string_to_key(const struct krb5_keytypes *enc,
256 const krb5_data *string,
257 const krb5_data *salt,
258 const krb5_data *params,
259 krb5_keyblock *key);
260 krb5_error_code krb5int_aes_string_to_key(const struct krb5_keytypes *enc,
261 const krb5_data *string,
262 const krb5_data *salt,
263 const krb5_data *params,
264 krb5_keyblock *key);
265 krb5_error_code krb5int_camellia_string_to_key(const struct krb5_keytypes *enc,
266 const krb5_data *string,
267 const krb5_data *salt,
268 const krb5_data *params,
269 krb5_keyblock *key);
270 krb5_error_code krb5int_aes2_string_to_key(const struct krb5_keytypes *enc,
271 const krb5_data *string,
272 const krb5_data *salt,
273 const krb5_data *params,
274 krb5_keyblock *key);
275
276 /* Random to key */
277 krb5_error_code k5_rand2key_direct(const krb5_data *randombits,
278 krb5_keyblock *keyblock);
279 krb5_error_code k5_rand2key_des(const krb5_data *randombits,
280 krb5_keyblock *keyblock);
281 krb5_error_code k5_rand2key_des3(const krb5_data *randombits,
282 krb5_keyblock *keyblock);
283
284 /* Pseudo-random function */
285 krb5_error_code krb5int_des_prf(const struct krb5_keytypes *ktp,
286 krb5_key key, const krb5_data *in,
287 krb5_data *out);
288 krb5_error_code krb5int_arcfour_prf(const struct krb5_keytypes *ktp,
289 krb5_key key, const krb5_data *in,
290 krb5_data *out);
291 krb5_error_code krb5int_dk_prf(const struct krb5_keytypes *ktp, krb5_key key,
292 const krb5_data *in, krb5_data *out);
293 krb5_error_code krb5int_dk_cmac_prf(const struct krb5_keytypes *ktp,
294 krb5_key key, const krb5_data *in,
295 krb5_data *out);
296 krb5_error_code krb5int_aes2_prf(const struct krb5_keytypes *ktp, krb5_key key,
297 const krb5_data *in, krb5_data *out);
298
299 /*** Prototypes for cksumtype handler functions ***/
300
301 krb5_error_code krb5int_unkeyed_checksum(const struct krb5_cksumtypes *ctp,
302 krb5_key key, krb5_keyusage usage,
303 const krb5_crypto_iov *data,
304 size_t num_data,
305 krb5_data *output);
306 krb5_error_code krb5int_hmacmd5_checksum(const struct krb5_cksumtypes *ctp,
307 krb5_key key, krb5_keyusage usage,
308 const krb5_crypto_iov *data,
309 size_t num_data,
310 krb5_data *output);
311 krb5_error_code krb5int_dk_checksum(const struct krb5_cksumtypes *ctp,
312 krb5_key key, krb5_keyusage usage,
313 const krb5_crypto_iov *data,
314 size_t num_data, krb5_data *output);
315 krb5_error_code krb5int_dk_cmac_checksum(const struct krb5_cksumtypes *ctp,
316 krb5_key key, krb5_keyusage usage,
317 const krb5_crypto_iov *data,
318 size_t num_data, krb5_data *output);
319 krb5_error_code krb5int_etm_checksum(const struct krb5_cksumtypes *ctp,
320 krb5_key key, krb5_keyusage usage,
321 const krb5_crypto_iov *data,
322 size_t num_data, krb5_data *output);
323
324 /*** Key derivation functions ***/
325
326 enum deriv_alg {
327 DERIVE_RFC3961, /* RFC 3961 section 5.1 */
328 DERIVE_SP800_108_CMAC, /* NIST SP 800-108 with CMAC as PRF */
329 DERIVE_SP800_108_HMAC /* NIST SP 800-108 with HMAC as PRF */
330 };
331
332 krb5_error_code krb5int_derive_keyblock(const struct krb5_enc_provider *enc,
333 const struct krb5_hash_provider *hash,
334 krb5_key inkey, krb5_keyblock *outkey,
335 const krb5_data *in_constant,
336 enum deriv_alg alg);
337 krb5_error_code krb5int_derive_key(const struct krb5_enc_provider *enc,
338 const struct krb5_hash_provider *hash,
339 krb5_key inkey, krb5_key *outkey,
340 const krb5_data *in_constant,
341 enum deriv_alg alg);
342 krb5_error_code krb5int_derive_random(const struct krb5_enc_provider *enc,
343 const struct krb5_hash_provider *hash,
344 krb5_key inkey, krb5_data *outrnd,
345 const krb5_data *in_constant,
346 enum deriv_alg alg);
347 krb5_error_code
348 k5_sp800_108_counter_hmac(const struct krb5_hash_provider *hash,
349 krb5_key inkey, krb5_data *outrnd,
350 const krb5_data *label, const krb5_data *context);
351
352 /*** Miscellaneous prototypes ***/
353
354 /* nfold algorithm from RFC 3961 */
355 void krb5int_nfold(unsigned int inbits, const unsigned char *in,
356 unsigned int outbits, unsigned char *out);
357
358 /* Compute a CMAC checksum over data. */
359 krb5_error_code krb5int_cmac_checksum(const struct krb5_enc_provider *enc,
360 krb5_key key,
361 const krb5_crypto_iov *data,
362 size_t num_data,
363 krb5_data *output);
364
365 /* Translate an RFC 3961 key usage to a Microsoft RC4 usage. */
366 krb5_keyusage krb5int_arcfour_translate_usage(krb5_keyusage usage);
367
368 /* Ensure library initialization has occurred. */
369 int krb5int_crypto_init(void);
370
371 /* DES default state initialization handler (used by module enc providers). */
372 krb5_error_code krb5int_des_init_state(const krb5_keyblock *key,
373 krb5_keyusage keyusage,
374 krb5_data *state_out);
375
376 /* Default state cleanup handler (used by module enc providers). */
377 void krb5int_default_free_state(krb5_data *state);
378
379 /*** Input/output vector processing declarations **/
380
381 #define ENCRYPT_CONF_IOV(_iov) ((_iov)->flags == KRB5_CRYPTO_TYPE_HEADER)
382
383 #define ENCRYPT_DATA_IOV(_iov) ((_iov)->flags == KRB5_CRYPTO_TYPE_DATA || \
384 (_iov)->flags == KRB5_CRYPTO_TYPE_PADDING)
385
386 #define ENCRYPT_IOV(_iov) (ENCRYPT_CONF_IOV(_iov) || ENCRYPT_DATA_IOV(_iov))
387
388 #define SIGN_IOV(_iov) (ENCRYPT_IOV(_iov) || \
389 (_iov)->flags == KRB5_CRYPTO_TYPE_SIGN_ONLY )
390
391 struct iov_cursor {
392 const krb5_crypto_iov *iov; /* iov array we are iterating over */
393 size_t iov_count; /* size of iov array */
394 size_t block_size; /* size of blocks we will be obtaining */
395 krb5_boolean signing; /* should we process SIGN_ONLY blocks */
396 size_t in_iov; /* read index into iov array */
397 size_t in_pos; /* read index into iov contents */
398 size_t out_iov; /* write index into iov array */
399 size_t out_pos; /* write index into iov contents */
400 };
401
402 krb5_crypto_iov *krb5int_c_locate_iov(krb5_crypto_iov *data, size_t num_data,
403 krb5_cryptotype type);
404
405 krb5_error_code krb5int_c_iov_decrypt_stream(const struct krb5_keytypes *ktp,
406 krb5_key key,
407 krb5_keyusage keyusage,
408 const krb5_data *ivec,
409 krb5_crypto_iov *data,
410 size_t num_data);
411
412 unsigned int krb5int_c_padding_length(const struct krb5_keytypes *ktp,
413 size_t data_length);
414
415 void k5_iov_cursor_init(struct iov_cursor *cursor, const krb5_crypto_iov *iov,
416 size_t count, size_t block_size, krb5_boolean signing);
417
418 krb5_boolean k5_iov_cursor_get(struct iov_cursor *cursor,
419 unsigned char *block);
420
421 void k5_iov_cursor_put(struct iov_cursor *cursor, unsigned char *block);
422
423 /*** Crypto module declarations ***/
424
425 /* Modules must implement the k5_sha256() function prototyped in k5-int.h. */
426
427 /* Modules must implement the following enc_providers and hash_providers: */
428 extern const struct krb5_enc_provider krb5int_enc_des3;
429 extern const struct krb5_enc_provider krb5int_enc_arcfour;
430 extern const struct krb5_enc_provider krb5int_enc_aes128;
431 extern const struct krb5_enc_provider krb5int_enc_aes256;
432 extern const struct krb5_enc_provider krb5int_enc_aes128_ctr;
433 extern const struct krb5_enc_provider krb5int_enc_aes256_ctr;
434 extern const struct krb5_enc_provider krb5int_enc_camellia128;
435 extern const struct krb5_enc_provider krb5int_enc_camellia256;
436
437 extern const struct krb5_hash_provider krb5int_hash_md4;
438 extern const struct krb5_hash_provider krb5int_hash_md5;
439 extern const struct krb5_hash_provider krb5int_hash_sha1;
440 extern const struct krb5_hash_provider krb5int_hash_sha256;
441 extern const struct krb5_hash_provider krb5int_hash_sha384;
442
443 /* Modules must implement the following functions. */
444
445 /* Set the parity bits to the correct values in keybits. */
446 void k5_des_fixup_key_parity(unsigned char *keybits);
447
448 /* Return true if keybits is a weak or semi-weak DES key. */
449 krb5_boolean k5_des_is_weak_key(unsigned char *keybits);
450
451 /* Compute an HMAC using the provided hash function, key, and data, storing the
452 * result into output (caller-allocated). */
453 krb5_error_code krb5int_hmac(const struct krb5_hash_provider *hash,
454 krb5_key key, const krb5_crypto_iov *data,
455 size_t num_data, krb5_data *output);
456
457 /* As above, using a keyblock as the key input. */
458 krb5_error_code krb5int_hmac_keyblock(const struct krb5_hash_provider *hash,
459 const krb5_keyblock *keyblock,
460 const krb5_crypto_iov *data,
461 size_t num_data, krb5_data *output);
462
463 /*
464 * Compute the PBKDF2 (see RFC 2898) of password and salt, with the specified
465 * count, using HMAC with the specified hash as the pseudo-random function,
466 * storing the result into out (caller-allocated).
467 */
468 krb5_error_code krb5int_pbkdf2_hmac(const struct krb5_hash_provider *hash,
469 const krb5_data *out, unsigned long count,
470 const krb5_data *password,
471 const krb5_data *salt);
472
473 /* The following are used by test programs and are just handler functions from
474 * the AES and Camellia enc providers. */
475 krb5_error_code krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec,
476 krb5_crypto_iov *data, size_t num_data);
477 krb5_error_code krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec,
478 krb5_crypto_iov *data, size_t num_data);
479 krb5_error_code krb5int_camellia_cbc_mac(krb5_key key,
480 const krb5_crypto_iov *data,
481 size_t num_data, const krb5_data *iv,
482 krb5_data *output);
483
484 /* These can be used to safely set up and tear down module global state. */
485 int krb5int_crypto_impl_init(void);
486 void krb5int_crypto_impl_cleanup(void);
487
488 /*
489 * Modules must provide a crypto_mod.h header at the top level. To work with
490 * the default PRNG module (prng_fortuna.c), crypto_mod.h must #define or
491 * prototype the following symbols:
492 *
493 * aes_encrypt_ctx - Stack-allocatable type for an AES-256 key schedule
494 * k5_aes_encrypt_key256(key, ctxptr) -- initialize an AES-256 key schedule
495 * k5_aes_encrypt(in, out, ctxptr) -- encrypt a block
496 * SHA256_CTX - Stack-allocatable type for a SHA-256 hash state
497 * k5_sha256_init(ctxptr) - Initialize a hash state
498 * k5_sha256_update(ctxptr, data, size) -- Hash some data
499 * k5_sha256_final(ctxptr, out) -- Finalize a state, writing hash into out
500 *
501 * These functions must never fail on valid inputs, and contexts must remain
502 * valid across forks. If the module cannot meet those constraints, then it
503 * should provide its own PRNG module and the build system should ensure that
504 * it is used.
505 *
506 * The function symbols named above are also in the library export list (so
507 * they can be used by the t_fortuna.c test code), so even if the module
508 * defines them away or doesn't work with Fortuna, the module must provide
509 * stubs; see stubs.c in the openssl module for examples.
510 */
511
512 #include <crypto_mod.h>
513
514 /*** PRNG module declarations ***/
515
516 /*
517 * PRNG modules must implement the following APIs from krb5.h:
518 * krb5_c_random_add_entropy
519 * krb5_c_random_make_octets
520 * krb5_c_random_os_entropy
521 *
522 * PRNG modules should implement these functions. They are called from the
523 * crypto library init and cleanup functions, and can be used to setup and tear
524 * down static state without thread safety concerns.
525 */
526 int k5_prng_init(void);
527 void k5_prng_cleanup(void);
528
529 /* Used by PRNG modules to gather OS entropy. Returns true on success. */
530 krb5_boolean k5_get_os_entropy(unsigned char *buf, size_t len, int strong);
531
532 /*** Inline helper functions ***/
533
534 /* Find an enctype by number in the enctypes table. */
535 static inline const struct krb5_keytypes *
find_enctype(krb5_enctype enctype)536 find_enctype(krb5_enctype enctype)
537 {
538 int i;
539
540 for (i = 0; i < krb5int_enctypes_length; i++) {
541 if (krb5int_enctypes_list[i].etype == enctype)
542 break;
543 }
544
545 if (i == krb5int_enctypes_length)
546 return NULL;
547 return &krb5int_enctypes_list[i];
548 }
549
550 /* Find a checksum type by number in the cksumtypes table. */
551 static inline const struct krb5_cksumtypes *
find_cksumtype(krb5_cksumtype ctype)552 find_cksumtype(krb5_cksumtype ctype)
553 {
554 size_t i;
555
556 for (i = 0; i < krb5int_cksumtypes_length; i++) {
557 if (krb5int_cksumtypes_list[i].ctype == ctype)
558 break;
559 }
560
561 if (i == krb5int_cksumtypes_length)
562 return NULL;
563 return &krb5int_cksumtypes_list[i];
564 }
565
566 /* Verify that a key is appropriate for a checksum type. */
567 static inline krb5_error_code
verify_key(const struct krb5_cksumtypes * ctp,krb5_key key)568 verify_key(const struct krb5_cksumtypes *ctp, krb5_key key)
569 {
570 const struct krb5_keytypes *ktp;
571
572 ktp = key ? find_enctype(key->keyblock.enctype) : NULL;
573 if (ctp->enc != NULL && (!ktp || ktp->enc != ctp->enc))
574 return KRB5_BAD_ENCTYPE;
575 if (key && (!ktp || key->keyblock.length != ktp->enc->keylength))
576 return KRB5_BAD_KEYSIZE;
577 return 0;
578 }
579
580 /* Encrypt one block of plaintext in place, for block ciphers. */
581 static inline krb5_error_code
encrypt_block(const struct krb5_enc_provider * enc,krb5_key key,krb5_data * block)582 encrypt_block(const struct krb5_enc_provider *enc, krb5_key key,
583 krb5_data *block)
584 {
585 krb5_crypto_iov iov;
586
587 /* Verify that this is a block cipher and block is the right length. */
588 if (block->length != enc->block_size || enc->block_size == 1)
589 return EINVAL;
590 iov.flags = KRB5_CRYPTO_TYPE_DATA;
591 iov.data = *block;
592 if (enc->cbc_mac != NULL) /* One-block cbc-mac with no ivec. */
593 return enc->cbc_mac(key, &iov, 1, NULL, block);
594 else /* Assume cbc-mode encrypt. */
595 return enc->encrypt(key, 0, &iov, 1);
596 }
597
598 /* Return the total length of the to-be-signed or to-be-encrypted buffers in an
599 * iov chain. */
600 static inline size_t
iov_total_length(const krb5_crypto_iov * data,size_t num_data,krb5_boolean signing)601 iov_total_length(const krb5_crypto_iov *data, size_t num_data,
602 krb5_boolean signing)
603 {
604 size_t i, total = 0;
605
606 for (i = 0; i < num_data; i++) {
607 if (signing ? SIGN_IOV(&data[i]) : ENCRYPT_IOV(&data[i]))
608 total += data[i].data.length;
609 }
610 return total;
611 }
612
613 /*
614 * Return the number of contiguous blocks available within the current input
615 * IOV of the cursor c, so that the caller can do in-place encryption.
616 * Do not call if c might be exhausted.
617 */
618 static inline size_t
iov_cursor_contig_blocks(struct iov_cursor * c)619 iov_cursor_contig_blocks(struct iov_cursor *c)
620 {
621 return (c->iov[c->in_iov].data.length - c->in_pos) / c->block_size;
622 }
623
624 /* Return the current input pointer within the cursor c. Do not call if c
625 * might be exhausted. */
626 static inline unsigned char *
iov_cursor_ptr(struct iov_cursor * c)627 iov_cursor_ptr(struct iov_cursor *c)
628 {
629 return (unsigned char *)&c->iov[c->in_iov].data.data[c->in_pos];
630 }
631
632 /*
633 * Advance the input and output pointers of c by nblocks blocks. nblocks must
634 * not be greater than the return value of iov_cursor_contig_blocks, and the
635 * input and output positions must be identical.
636 */
637 static inline void
iov_cursor_advance(struct iov_cursor * c,size_t nblocks)638 iov_cursor_advance(struct iov_cursor *c, size_t nblocks)
639 {
640 c->in_pos += nblocks * c->block_size;
641 c->out_pos += nblocks * c->block_size;
642 }
643
644 #endif /* CRYPTO_INT_H */
645