2 * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include "krb5_locl.h"
36 struct _krb5_key_usage
{
38 struct _krb5_key_data key
;
42 #ifndef HEIMDAL_SMALLER
43 #define DES3_OLD_ENCTYPE 1
46 static krb5_error_code
_get_derived_key(krb5_context
, krb5_crypto
,
47 unsigned, struct _krb5_key_data
**);
48 static struct _krb5_key_data
*_new_derived_key(krb5_crypto crypto
, unsigned usage
);
50 static void free_key_schedule(krb5_context
,
51 struct _krb5_key_data
*,
52 struct _krb5_encryption_type
*);
54 /************************************************************
56 ************************************************************/
58 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
59 krb5_enctype_keysize(krb5_context context
,
63 struct _krb5_encryption_type
*et
= _krb5_find_enctype(type
);
65 krb5_set_error_message(context
, KRB5_PROG_ETYPE_NOSUPP
,
66 N_("encryption type %d not supported", ""),
68 return KRB5_PROG_ETYPE_NOSUPP
;
70 *keysize
= et
->keytype
->size
;
74 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
75 krb5_enctype_keybits(krb5_context context
,
79 struct _krb5_encryption_type
*et
= _krb5_find_enctype(type
);
81 krb5_set_error_message(context
, KRB5_PROG_ETYPE_NOSUPP
,
82 "encryption type %d not supported",
84 return KRB5_PROG_ETYPE_NOSUPP
;
86 *keybits
= et
->keytype
->bits
;
90 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
91 krb5_generate_random_keyblock(krb5_context context
,
96 struct _krb5_encryption_type
*et
= _krb5_find_enctype(type
);
98 krb5_set_error_message(context
, KRB5_PROG_ETYPE_NOSUPP
,
99 N_("encryption type %d not supported", ""),
101 return KRB5_PROG_ETYPE_NOSUPP
;
103 ret
= krb5_data_alloc(&key
->keyvalue
, et
->keytype
->size
);
107 if(et
->keytype
->random_key
)
108 (*et
->keytype
->random_key
)(context
, key
);
110 krb5_generate_random_block(key
->keyvalue
.data
,
111 key
->keyvalue
.length
);
115 static krb5_error_code
116 _key_schedule(krb5_context context
,
117 struct _krb5_key_data
*key
)
120 struct _krb5_encryption_type
*et
= _krb5_find_enctype(key
->key
->keytype
);
121 struct _krb5_key_type
*kt
;
124 krb5_set_error_message (context
, KRB5_PROG_ETYPE_NOSUPP
,
125 N_("encryption type %d not supported", ""),
127 return KRB5_PROG_ETYPE_NOSUPP
;
132 if(kt
->schedule
== NULL
)
134 if (key
->schedule
!= NULL
)
136 ALLOC(key
->schedule
, 1);
137 if(key
->schedule
== NULL
) {
138 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
141 ret
= krb5_data_alloc(key
->schedule
, kt
->schedule_size
);
144 key
->schedule
= NULL
;
147 (*kt
->schedule
)(context
, kt
, key
);
151 /************************************************************
153 ************************************************************/
155 static krb5_error_code
156 SHA1_checksum(krb5_context context
,
157 struct _krb5_key_data
*key
,
163 if (EVP_Digest(data
, len
, C
->checksum
.data
, NULL
, EVP_sha1(), NULL
) != 1)
164 krb5_abortx(context
, "sha1 checksum failed");
168 /* HMAC according to RFC2104 */
170 _krb5_internal_hmac(krb5_context context
,
171 struct _krb5_checksum_type
*cm
,
175 struct _krb5_key_data
*keyblock
,
178 unsigned char *ipad
, *opad
;
183 ipad
= malloc(cm
->blocksize
+ len
);
186 opad
= malloc(cm
->blocksize
+ cm
->checksumsize
);
191 memset(ipad
, 0x36, cm
->blocksize
);
192 memset(opad
, 0x5c, cm
->blocksize
);
194 if(keyblock
->key
->keyvalue
.length
> cm
->blocksize
){
195 (*cm
->checksum
)(context
,
197 keyblock
->key
->keyvalue
.data
,
198 keyblock
->key
->keyvalue
.length
,
201 key
= result
->checksum
.data
;
202 key_len
= result
->checksum
.length
;
204 key
= keyblock
->key
->keyvalue
.data
;
205 key_len
= keyblock
->key
->keyvalue
.length
;
207 for(i
= 0; i
< key_len
; i
++){
211 memcpy(ipad
+ cm
->blocksize
, data
, len
);
212 (*cm
->checksum
)(context
, keyblock
, ipad
, cm
->blocksize
+ len
,
214 memcpy(opad
+ cm
->blocksize
, result
->checksum
.data
,
215 result
->checksum
.length
);
216 (*cm
->checksum
)(context
, keyblock
, opad
,
217 cm
->blocksize
+ cm
->checksumsize
, usage
, result
);
218 memset(ipad
, 0, cm
->blocksize
+ len
);
220 memset(opad
, 0, cm
->blocksize
+ cm
->checksumsize
);
226 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
227 krb5_hmac(krb5_context context
,
228 krb5_cksumtype cktype
,
235 struct _krb5_checksum_type
*c
= _krb5_find_checksum(cktype
);
236 struct _krb5_key_data kd
;
240 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
241 N_("checksum type %d not supported", ""),
243 return KRB5_PROG_SUMTYPE_NOSUPP
;
249 ret
= _krb5_internal_hmac(context
, c
, data
, len
, usage
, &kd
, result
);
252 krb5_free_data(context
, kd
.schedule
);
258 _krb5_SP_HMAC_SHA1_checksum(krb5_context context
,
259 struct _krb5_key_data
*key
,
265 struct _krb5_checksum_type
*c
= _krb5_find_checksum(CKSUMTYPE_SHA1
);
270 res
.checksum
.data
= sha1_data
;
271 res
.checksum
.length
= sizeof(sha1_data
);
273 ret
= _krb5_internal_hmac(context
, c
, data
, len
, usage
, key
, &res
);
275 krb5_abortx(context
, "hmac failed");
276 memcpy(result
->checksum
.data
, res
.checksum
.data
, result
->checksum
.length
);
280 struct _krb5_checksum_type _krb5_checksum_sha1
= {
290 struct _krb5_checksum_type
*
291 _krb5_find_checksum(krb5_cksumtype type
)
294 for(i
= 0; i
< _krb5_num_checksums
; i
++)
295 if(_krb5_checksum_types
[i
]->type
== type
)
296 return _krb5_checksum_types
[i
];
300 static krb5_error_code
301 get_checksum_key(krb5_context context
,
303 unsigned usage
, /* not krb5_key_usage */
304 struct _krb5_checksum_type
*ct
,
305 struct _krb5_key_data
**key
)
307 krb5_error_code ret
= 0;
309 if(ct
->flags
& F_DERIVED
)
310 ret
= _get_derived_key(context
, crypto
, usage
, key
);
311 else if(ct
->flags
& F_VARIANT
) {
314 *key
= _new_derived_key(crypto
, 0xff/* KRB5_KU_RFC1510_VARIANT */);
316 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
319 ret
= krb5_copy_keyblock(context
, crypto
->key
.key
, &(*key
)->key
);
322 for(i
= 0; i
< (*key
)->key
->keyvalue
.length
; i
++)
323 ((unsigned char*)(*key
)->key
->keyvalue
.data
)[i
] ^= 0xF0;
328 ret
= _key_schedule(context
, *key
);
332 static krb5_error_code
333 create_checksum (krb5_context context
,
334 struct _krb5_checksum_type
*ct
,
342 struct _krb5_key_data
*dkey
;
345 if (ct
->flags
& F_DISABLED
) {
346 krb5_clear_error_message (context
);
347 return KRB5_PROG_SUMTYPE_NOSUPP
;
349 keyed_checksum
= (ct
->flags
& F_KEYED
) != 0;
350 if(keyed_checksum
&& crypto
== NULL
) {
351 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
352 N_("Checksum type %s is keyed but no "
353 "crypto context (key) was passed in", ""),
355 return KRB5_PROG_SUMTYPE_NOSUPP
; /* XXX */
358 ret
= get_checksum_key(context
, crypto
, usage
, ct
, &dkey
);
363 result
->cksumtype
= ct
->type
;
364 ret
= krb5_data_alloc(&result
->checksum
, ct
->checksumsize
);
367 return (*ct
->checksum
)(context
, dkey
, data
, len
, usage
, result
);
371 arcfour_checksum_p(struct _krb5_checksum_type
*ct
, krb5_crypto crypto
)
373 return (ct
->type
== CKSUMTYPE_HMAC_MD5
) &&
374 (crypto
->key
.key
->keytype
== KEYTYPE_ARCFOUR
);
377 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
378 krb5_create_checksum(krb5_context context
,
380 krb5_key_usage usage
,
386 struct _krb5_checksum_type
*ct
= NULL
;
389 /* type 0 -> pick from crypto */
391 ct
= _krb5_find_checksum(type
);
393 ct
= crypto
->et
->keyed_checksum
;
395 ct
= crypto
->et
->checksum
;
399 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
400 N_("checksum type %d not supported", ""),
402 return KRB5_PROG_SUMTYPE_NOSUPP
;
405 if (arcfour_checksum_p(ct
, crypto
)) {
407 _krb5_usage2arcfour(context
, &keyusage
);
409 keyusage
= CHECKSUM_USAGE(usage
);
411 return create_checksum(context
, ct
, crypto
, keyusage
,
415 static krb5_error_code
416 verify_checksum(krb5_context context
,
418 unsigned usage
, /* not krb5_key_usage */
424 struct _krb5_key_data
*dkey
;
427 struct _krb5_checksum_type
*ct
;
429 ct
= _krb5_find_checksum(cksum
->cksumtype
);
430 if (ct
== NULL
|| (ct
->flags
& F_DISABLED
)) {
431 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
432 N_("checksum type %d not supported", ""),
434 return KRB5_PROG_SUMTYPE_NOSUPP
;
436 if(ct
->checksumsize
!= cksum
->checksum
.length
) {
437 krb5_clear_error_message (context
);
438 krb5_set_error_message(context
, KRB5KRB_AP_ERR_BAD_INTEGRITY
,
439 N_("Decrypt integrity check failed for checksum type %s, "
440 "length was %u, expected %u", ""),
441 ct
->name
, (unsigned)cksum
->checksum
.length
,
442 (unsigned)ct
->checksumsize
);
444 return KRB5KRB_AP_ERR_BAD_INTEGRITY
; /* XXX */
446 keyed_checksum
= (ct
->flags
& F_KEYED
) != 0;
448 struct _krb5_checksum_type
*kct
;
449 if (crypto
== NULL
) {
450 krb5_set_error_message(context
, KRB5_PROG_SUMTYPE_NOSUPP
,
451 N_("Checksum type %s is keyed but no "
452 "crypto context (key) was passed in", ""),
454 return KRB5_PROG_SUMTYPE_NOSUPP
; /* XXX */
456 kct
= crypto
->et
->keyed_checksum
;
457 if (kct
== NULL
|| kct
->type
!= ct
->type
) {
458 krb5_set_error_message(context
, KRB5_PROG_SUMTYPE_NOSUPP
,
459 N_("Checksum type %s is keyed, but "
460 "the key type %s passed didnt have that checksum "
461 "type as the keyed type", ""),
462 ct
->name
, crypto
->et
->name
);
463 return KRB5_PROG_SUMTYPE_NOSUPP
; /* XXX */
466 ret
= get_checksum_key(context
, crypto
, usage
, ct
, &dkey
);
473 * If checksum have a verify function, lets use that instead of
474 * calling ->checksum and then compare result.
478 ret
= (*ct
->verify
)(context
, dkey
, data
, len
, usage
, cksum
);
480 krb5_set_error_message(context
, ret
,
481 N_("Decrypt integrity check failed for checksum "
482 "type %s, key type %s", ""),
483 ct
->name
, (crypto
!= NULL
)? crypto
->et
->name
: "(none)");
487 ret
= krb5_data_alloc (&c
.checksum
, ct
->checksumsize
);
491 ret
= (*ct
->checksum
)(context
, dkey
, data
, len
, usage
, &c
);
493 krb5_data_free(&c
.checksum
);
497 if(krb5_data_ct_cmp(&c
.checksum
, &cksum
->checksum
) != 0) {
498 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
499 krb5_set_error_message(context
, ret
,
500 N_("Decrypt integrity check failed for checksum "
501 "type %s, key type %s", ""),
502 ct
->name
, crypto
? crypto
->et
->name
: "(unkeyed)");
506 krb5_data_free (&c
.checksum
);
510 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
511 krb5_verify_checksum(krb5_context context
,
513 krb5_key_usage usage
,
518 struct _krb5_checksum_type
*ct
;
521 ct
= _krb5_find_checksum(cksum
->cksumtype
);
523 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
524 N_("checksum type %d not supported", ""),
526 return KRB5_PROG_SUMTYPE_NOSUPP
;
529 if (arcfour_checksum_p(ct
, crypto
)) {
531 _krb5_usage2arcfour(context
, &keyusage
);
533 keyusage
= CHECKSUM_USAGE(usage
);
535 return verify_checksum(context
, crypto
, keyusage
,
539 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
540 krb5_crypto_get_checksum_type(krb5_context context
,
542 krb5_cksumtype
*type
)
544 struct _krb5_checksum_type
*ct
= NULL
;
546 if (crypto
!= NULL
) {
547 ct
= crypto
->et
->keyed_checksum
;
549 ct
= crypto
->et
->checksum
;
553 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
554 N_("checksum type not found", ""));
555 return KRB5_PROG_SUMTYPE_NOSUPP
;
564 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
565 krb5_checksumsize(krb5_context context
,
569 struct _krb5_checksum_type
*ct
= _krb5_find_checksum(type
);
571 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
572 N_("checksum type %d not supported", ""),
574 return KRB5_PROG_SUMTYPE_NOSUPP
;
576 *size
= ct
->checksumsize
;
580 KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
581 krb5_checksum_is_keyed(krb5_context context
,
584 struct _krb5_checksum_type
*ct
= _krb5_find_checksum(type
);
587 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
588 N_("checksum type %d not supported", ""),
590 return KRB5_PROG_SUMTYPE_NOSUPP
;
592 return ct
->flags
& F_KEYED
;
595 KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
596 krb5_checksum_is_collision_proof(krb5_context context
,
599 struct _krb5_checksum_type
*ct
= _krb5_find_checksum(type
);
602 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
603 N_("checksum type %d not supported", ""),
605 return KRB5_PROG_SUMTYPE_NOSUPP
;
607 return ct
->flags
& F_CPROOF
;
610 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
611 krb5_checksum_disable(krb5_context context
,
614 struct _krb5_checksum_type
*ct
= _krb5_find_checksum(type
);
617 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
618 N_("checksum type %d not supported", ""),
620 return KRB5_PROG_SUMTYPE_NOSUPP
;
622 ct
->flags
|= F_DISABLED
;
626 /************************************************************
628 ************************************************************/
630 struct _krb5_encryption_type
*
631 _krb5_find_enctype(krb5_enctype type
)
634 for(i
= 0; i
< _krb5_num_etypes
; i
++)
635 if(_krb5_etypes
[i
]->type
== type
)
636 return _krb5_etypes
[i
];
641 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
642 krb5_enctype_to_string(krb5_context context
,
646 struct _krb5_encryption_type
*e
;
647 e
= _krb5_find_enctype(etype
);
649 krb5_set_error_message (context
, KRB5_PROG_ETYPE_NOSUPP
,
650 N_("encryption type %d not supported", ""),
653 return KRB5_PROG_ETYPE_NOSUPP
;
655 *string
= strdup(e
->name
);
656 if(*string
== NULL
) {
657 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
663 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
664 krb5_string_to_enctype(krb5_context context
,
669 for(i
= 0; i
< _krb5_num_etypes
; i
++)
670 if(strcasecmp(_krb5_etypes
[i
]->name
, string
) == 0){
671 *etype
= _krb5_etypes
[i
]->type
;
674 krb5_set_error_message (context
, KRB5_PROG_ETYPE_NOSUPP
,
675 N_("encryption type %s not supported", ""),
677 return KRB5_PROG_ETYPE_NOSUPP
;
680 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
681 krb5_enctype_to_keytype(krb5_context context
,
683 krb5_keytype
*keytype
)
685 struct _krb5_encryption_type
*e
= _krb5_find_enctype(etype
);
687 krb5_set_error_message (context
, KRB5_PROG_ETYPE_NOSUPP
,
688 N_("encryption type %d not supported", ""),
690 return KRB5_PROG_ETYPE_NOSUPP
;
692 *keytype
= e
->keytype
->type
; /* XXX */
697 * Check if a enctype is valid, return 0 if it is.
699 * @param context Kerberos context
700 * @param etype enctype to check if its valid or not
702 * @return Return an error code for an failure or 0 on success (enctype valid).
703 * @ingroup krb5_crypto
706 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
707 krb5_enctype_valid(krb5_context context
,
710 struct _krb5_encryption_type
*e
= _krb5_find_enctype(etype
);
711 if(e
&& (e
->flags
& F_DISABLED
) == 0)
714 return KRB5_PROG_ETYPE_NOSUPP
;
716 krb5_set_error_message (context
, KRB5_PROG_ETYPE_NOSUPP
,
717 N_("encryption type %d not supported", ""),
719 return KRB5_PROG_ETYPE_NOSUPP
;
721 /* Must be (e->flags & F_DISABLED) */
722 krb5_set_error_message (context
, KRB5_PROG_ETYPE_NOSUPP
,
723 N_("encryption type %s is disabled", ""),
725 return KRB5_PROG_ETYPE_NOSUPP
;
729 * Return the coresponding encryption type for a checksum type.
731 * @param context Kerberos context
732 * @param ctype The checksum type to get the result enctype for
733 * @param etype The returned encryption, when the matching etype is
734 * not found, etype is set to ETYPE_NULL.
736 * @return Return an error code for an failure or 0 on success.
737 * @ingroup krb5_crypto
741 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
742 krb5_cksumtype_to_enctype(krb5_context context
,
743 krb5_cksumtype ctype
,
750 for(i
= 0; i
< _krb5_num_etypes
; i
++) {
751 if(_krb5_etypes
[i
]->keyed_checksum
&&
752 _krb5_etypes
[i
]->keyed_checksum
->type
== ctype
)
754 *etype
= _krb5_etypes
[i
]->type
;
759 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
760 N_("checksum type %d not supported", ""),
762 return KRB5_PROG_SUMTYPE_NOSUPP
;
766 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
767 krb5_cksumtype_valid(krb5_context context
,
768 krb5_cksumtype ctype
)
770 struct _krb5_checksum_type
*c
= _krb5_find_checksum(ctype
);
772 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
773 N_("checksum type %d not supported", ""),
775 return KRB5_PROG_SUMTYPE_NOSUPP
;
777 if (c
->flags
& F_DISABLED
) {
778 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
779 N_("checksum type %s is disabled", ""),
781 return KRB5_PROG_SUMTYPE_NOSUPP
;
788 derived_crypto(krb5_context context
,
791 return (crypto
->et
->flags
& F_DERIVED
) != 0;
795 special_crypto(krb5_context context
,
798 return (crypto
->et
->flags
& F_SPECIAL
) != 0;
801 #define CHECKSUMSIZE(C) ((C)->checksumsize)
802 #define CHECKSUMTYPE(C) ((C)->type)
804 static krb5_error_code
805 encrypt_internal_derived(krb5_context context
,
813 size_t sz
, block_sz
, checksum_sz
, total_sz
;
815 unsigned char *p
, *q
;
817 struct _krb5_key_data
*dkey
;
818 const struct _krb5_encryption_type
*et
= crypto
->et
;
820 checksum_sz
= CHECKSUMSIZE(et
->keyed_checksum
);
822 sz
= et
->confoundersize
+ len
;
823 block_sz
= (sz
+ et
->padsize
- 1) &~ (et
->padsize
- 1); /* pad */
824 total_sz
= block_sz
+ checksum_sz
;
825 p
= calloc(1, total_sz
);
827 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
832 krb5_generate_random_block(q
, et
->confoundersize
); /* XXX */
833 q
+= et
->confoundersize
;
834 memcpy(q
, data
, len
);
836 ret
= create_checksum(context
,
839 INTEGRITY_USAGE(usage
),
843 if(ret
== 0 && cksum
.checksum
.length
!= checksum_sz
) {
844 free_Checksum (&cksum
);
845 krb5_clear_error_message (context
);
846 ret
= KRB5_CRYPTO_INTERNAL
;
850 memcpy(p
+ block_sz
, cksum
.checksum
.data
, cksum
.checksum
.length
);
851 free_Checksum (&cksum
);
852 ret
= _get_derived_key(context
, crypto
, ENCRYPTION_USAGE(usage
), &dkey
);
855 ret
= _key_schedule(context
, dkey
);
858 ret
= (*et
->encrypt
)(context
, dkey
, p
, block_sz
, 1, usage
, ivec
);
862 result
->length
= total_sz
;
865 memset(p
, 0, total_sz
);
871 static krb5_error_code
872 encrypt_internal(krb5_context context
,
879 size_t sz
, block_sz
, checksum_sz
;
881 unsigned char *p
, *q
;
883 const struct _krb5_encryption_type
*et
= crypto
->et
;
885 checksum_sz
= CHECKSUMSIZE(et
->checksum
);
887 sz
= et
->confoundersize
+ checksum_sz
+ len
;
888 block_sz
= (sz
+ et
->padsize
- 1) &~ (et
->padsize
- 1); /* pad */
889 p
= calloc(1, block_sz
);
891 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
896 krb5_generate_random_block(q
, et
->confoundersize
); /* XXX */
897 q
+= et
->confoundersize
;
898 memset(q
, 0, checksum_sz
);
900 memcpy(q
, data
, len
);
902 ret
= create_checksum(context
,
909 if(ret
== 0 && cksum
.checksum
.length
!= checksum_sz
) {
910 krb5_clear_error_message (context
);
911 free_Checksum(&cksum
);
912 ret
= KRB5_CRYPTO_INTERNAL
;
916 memcpy(p
+ et
->confoundersize
, cksum
.checksum
.data
, cksum
.checksum
.length
);
917 free_Checksum(&cksum
);
918 ret
= _key_schedule(context
, &crypto
->key
);
921 ret
= (*et
->encrypt
)(context
, &crypto
->key
, p
, block_sz
, 1, 0, ivec
);
923 memset(p
, 0, block_sz
);
928 result
->length
= block_sz
;
931 memset(p
, 0, block_sz
);
936 static krb5_error_code
937 encrypt_internal_special(krb5_context context
,
945 struct _krb5_encryption_type
*et
= crypto
->et
;
946 size_t cksum_sz
= CHECKSUMSIZE(et
->checksum
);
947 size_t sz
= len
+ cksum_sz
+ et
->confoundersize
;
953 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
957 memset (p
, 0, cksum_sz
);
959 krb5_generate_random_block(p
, et
->confoundersize
);
960 p
+= et
->confoundersize
;
961 memcpy (p
, data
, len
);
962 ret
= (*et
->encrypt
)(context
, &crypto
->key
, tmp
, sz
, TRUE
, usage
, ivec
);
973 static krb5_error_code
974 decrypt_internal_derived(krb5_context context
,
986 struct _krb5_key_data
*dkey
;
987 struct _krb5_encryption_type
*et
= crypto
->et
;
990 checksum_sz
= CHECKSUMSIZE(et
->keyed_checksum
);
991 if (len
< checksum_sz
+ et
->confoundersize
) {
992 krb5_set_error_message(context
, KRB5_BAD_MSIZE
,
993 N_("Encrypted data shorter then "
994 "checksum + confunder", ""));
995 return KRB5_BAD_MSIZE
;
998 if (((len
- checksum_sz
) % et
->padsize
) != 0) {
999 krb5_clear_error_message(context
);
1000 return KRB5_BAD_MSIZE
;
1004 if(len
!= 0 && p
== NULL
) {
1005 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
1008 memcpy(p
, data
, len
);
1012 ret
= _get_derived_key(context
, crypto
, ENCRYPTION_USAGE(usage
), &dkey
);
1017 ret
= _key_schedule(context
, dkey
);
1022 ret
= (*et
->encrypt
)(context
, dkey
, p
, len
, 0, usage
, ivec
);
1028 cksum
.checksum
.data
= p
+ len
;
1029 cksum
.checksum
.length
= checksum_sz
;
1030 cksum
.cksumtype
= CHECKSUMTYPE(et
->keyed_checksum
);
1032 ret
= verify_checksum(context
,
1034 INTEGRITY_USAGE(usage
),
1042 l
= len
- et
->confoundersize
;
1043 memmove(p
, p
+ et
->confoundersize
, l
);
1044 result
->data
= realloc(p
, l
);
1045 if(result
->data
== NULL
&& l
!= 0) {
1047 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
1054 static krb5_error_code
1055 decrypt_internal(krb5_context context
,
1062 krb5_error_code ret
;
1065 size_t checksum_sz
, l
;
1066 struct _krb5_encryption_type
*et
= crypto
->et
;
1068 if ((len
% et
->padsize
) != 0) {
1069 krb5_clear_error_message(context
);
1070 return KRB5_BAD_MSIZE
;
1072 checksum_sz
= CHECKSUMSIZE(et
->checksum
);
1073 if (len
< checksum_sz
+ et
->confoundersize
) {
1074 krb5_set_error_message(context
, KRB5_BAD_MSIZE
,
1075 N_("Encrypted data shorter then "
1076 "checksum + confunder", ""));
1077 return KRB5_BAD_MSIZE
;
1081 if(len
!= 0 && p
== NULL
) {
1082 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
1085 memcpy(p
, data
, len
);
1087 ret
= _key_schedule(context
, &crypto
->key
);
1092 ret
= (*et
->encrypt
)(context
, &crypto
->key
, p
, len
, 0, 0, ivec
);
1097 ret
= krb5_data_copy(&cksum
.checksum
, p
+ et
->confoundersize
, checksum_sz
);
1102 memset(p
+ et
->confoundersize
, 0, checksum_sz
);
1103 cksum
.cksumtype
= CHECKSUMTYPE(et
->checksum
);
1104 ret
= verify_checksum(context
, NULL
, 0, p
, len
, &cksum
);
1105 free_Checksum(&cksum
);
1110 l
= len
- et
->confoundersize
- checksum_sz
;
1111 memmove(p
, p
+ et
->confoundersize
+ checksum_sz
, l
);
1112 result
->data
= realloc(p
, l
);
1113 if(result
->data
== NULL
&& l
!= 0) {
1115 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
1122 static krb5_error_code
1123 decrypt_internal_special(krb5_context context
,
1131 struct _krb5_encryption_type
*et
= crypto
->et
;
1132 size_t cksum_sz
= CHECKSUMSIZE(et
->checksum
);
1133 size_t sz
= len
- cksum_sz
- et
->confoundersize
;
1135 krb5_error_code ret
;
1137 if ((len
% et
->padsize
) != 0) {
1138 krb5_clear_error_message(context
);
1139 return KRB5_BAD_MSIZE
;
1141 if (len
< cksum_sz
+ et
->confoundersize
) {
1142 krb5_set_error_message(context
, KRB5_BAD_MSIZE
,
1143 N_("Encrypted data shorter then "
1144 "checksum + confunder", ""));
1145 return KRB5_BAD_MSIZE
;
1150 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
1153 memcpy(p
, data
, len
);
1155 ret
= (*et
->encrypt
)(context
, &crypto
->key
, p
, len
, FALSE
, usage
, ivec
);
1161 memmove (p
, p
+ cksum_sz
+ et
->confoundersize
, sz
);
1162 result
->data
= realloc(p
, sz
);
1163 if(result
->data
== NULL
&& sz
!= 0) {
1165 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
1168 result
->length
= sz
;
1172 static krb5_crypto_iov
*
1173 find_iv(krb5_crypto_iov
*data
, size_t num_data
, unsigned type
)
1176 for (i
= 0; i
< num_data
; i
++)
1177 if (data
[i
].flags
== type
)
1183 * Inline encrypt a kerberos message
1185 * @param context Kerberos context
1186 * @param crypto Kerberos crypto context
1187 * @param usage Key usage for this buffer
1188 * @param data array of buffers to process
1189 * @param num_data length of array
1190 * @param ivec initial cbc/cts vector
1192 * @return Return an error code or 0.
1193 * @ingroup krb5_crypto
1195 * Kerberos encrypted data look like this:
1197 * 1. KRB5_CRYPTO_TYPE_HEADER
1198 * 2. array [1,...] KRB5_CRYPTO_TYPE_DATA and array [0,...]
1199 * KRB5_CRYPTO_TYPE_SIGN_ONLY in any order, however the receiver
1200 * have to aware of the order. KRB5_CRYPTO_TYPE_SIGN_ONLY is
1201 * commonly used headers and trailers.
1202 * 3. KRB5_CRYPTO_TYPE_PADDING, at least on padsize long if padsize > 1
1203 * 4. KRB5_CRYPTO_TYPE_TRAILER
1206 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1207 krb5_encrypt_iov_ivec(krb5_context context
,
1210 krb5_crypto_iov
*data
,
1214 size_t headersz
, trailersz
, len
;
1216 size_t sz
, block_sz
, pad_sz
;
1218 unsigned char *p
, *q
;
1219 krb5_error_code ret
;
1220 struct _krb5_key_data
*dkey
;
1221 const struct _krb5_encryption_type
*et
= crypto
->et
;
1222 krb5_crypto_iov
*tiv
, *piv
, *hiv
;
1225 krb5_clear_error_message(context
);
1226 return KRB5_CRYPTO_INTERNAL
;
1229 if(!derived_crypto(context
, crypto
)) {
1230 krb5_clear_error_message(context
);
1231 return KRB5_CRYPTO_INTERNAL
;
1234 headersz
= et
->confoundersize
;
1235 trailersz
= CHECKSUMSIZE(et
->keyed_checksum
);
1237 for (len
= 0, i
= 0; i
< num_data
; i
++) {
1238 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
)
1240 len
+= data
[i
].data
.length
;
1243 sz
= headersz
+ len
;
1244 block_sz
= (sz
+ et
->padsize
- 1) &~ (et
->padsize
- 1); /* pad */
1246 pad_sz
= block_sz
- sz
;
1250 hiv
= find_iv(data
, num_data
, KRB5_CRYPTO_TYPE_HEADER
);
1251 if (hiv
== NULL
|| hiv
->data
.length
!= headersz
)
1252 return KRB5_BAD_MSIZE
;
1254 krb5_generate_random_block(hiv
->data
.data
, hiv
->data
.length
);
1257 piv
= find_iv(data
, num_data
, KRB5_CRYPTO_TYPE_PADDING
);
1258 /* its ok to have no TYPE_PADDING if there is no padding */
1259 if (piv
== NULL
&& pad_sz
!= 0)
1260 return KRB5_BAD_MSIZE
;
1262 if (piv
->data
.length
< pad_sz
)
1263 return KRB5_BAD_MSIZE
;
1264 piv
->data
.length
= pad_sz
;
1266 memset(piv
->data
.data
, pad_sz
, pad_sz
);
1272 tiv
= find_iv(data
, num_data
, KRB5_CRYPTO_TYPE_TRAILER
);
1273 if (tiv
== NULL
|| tiv
->data
.length
!= trailersz
)
1274 return KRB5_BAD_MSIZE
;
1277 * XXX replace with EVP_Sign? at least make create_checksum an iov
1279 * XXX CTS EVP is broken, can't handle multi buffers :(
1283 for (i
= 0; i
< num_data
; i
++) {
1284 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_SIGN_ONLY
)
1286 len
+= data
[i
].data
.length
;
1289 p
= q
= malloc(len
);
1291 memcpy(q
, hiv
->data
.data
, hiv
->data
.length
);
1292 q
+= hiv
->data
.length
;
1293 for (i
= 0; i
< num_data
; i
++) {
1294 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
&&
1295 data
[i
].flags
!= KRB5_CRYPTO_TYPE_SIGN_ONLY
)
1297 memcpy(q
, data
[i
].data
.data
, data
[i
].data
.length
);
1298 q
+= data
[i
].data
.length
;
1301 memset(q
, 0, piv
->data
.length
);
1303 ret
= create_checksum(context
,
1306 INTEGRITY_USAGE(usage
),
1311 if(ret
== 0 && cksum
.checksum
.length
!= trailersz
) {
1312 free_Checksum (&cksum
);
1313 krb5_clear_error_message (context
);
1314 ret
= KRB5_CRYPTO_INTERNAL
;
1319 /* save cksum at end */
1320 memcpy(tiv
->data
.data
, cksum
.checksum
.data
, cksum
.checksum
.length
);
1321 free_Checksum (&cksum
);
1323 /* XXX replace with EVP_Cipher */
1324 p
= q
= malloc(block_sz
);
1328 memcpy(q
, hiv
->data
.data
, hiv
->data
.length
);
1329 q
+= hiv
->data
.length
;
1331 for (i
= 0; i
< num_data
; i
++) {
1332 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
)
1334 memcpy(q
, data
[i
].data
.data
, data
[i
].data
.length
);
1335 q
+= data
[i
].data
.length
;
1338 memset(q
, 0, piv
->data
.length
);
1341 ret
= _get_derived_key(context
, crypto
, ENCRYPTION_USAGE(usage
), &dkey
);
1346 ret
= _key_schedule(context
, dkey
);
1352 ret
= (*et
->encrypt
)(context
, dkey
, p
, block_sz
, 1, usage
, ivec
);
1358 /* now copy data back to buffers */
1361 memcpy(hiv
->data
.data
, q
, hiv
->data
.length
);
1362 q
+= hiv
->data
.length
;
1364 for (i
= 0; i
< num_data
; i
++) {
1365 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
)
1367 memcpy(data
[i
].data
.data
, q
, data
[i
].data
.length
);
1368 q
+= data
[i
].data
.length
;
1371 memcpy(piv
->data
.data
, q
, pad_sz
);
1379 * Inline decrypt a Kerberos message.
1381 * @param context Kerberos context
1382 * @param crypto Kerberos crypto context
1383 * @param usage Key usage for this buffer
1384 * @param data array of buffers to process
1385 * @param num_data length of array
1386 * @param ivec initial cbc/cts vector
1388 * @return Return an error code or 0.
1389 * @ingroup krb5_crypto
1391 * 1. KRB5_CRYPTO_TYPE_HEADER
1392 * 2. one KRB5_CRYPTO_TYPE_DATA and array [0,...] of KRB5_CRYPTO_TYPE_SIGN_ONLY in
1393 * any order, however the receiver have to aware of the
1394 * order. KRB5_CRYPTO_TYPE_SIGN_ONLY is commonly used unencrypoted
1395 * protocol headers and trailers. The output data will be of same
1396 * size as the input data or shorter.
1399 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1400 krb5_decrypt_iov_ivec(krb5_context context
,
1403 krb5_crypto_iov
*data
,
1404 unsigned int num_data
,
1408 size_t headersz
, trailersz
, len
;
1410 unsigned char *p
, *q
;
1411 krb5_error_code ret
;
1412 struct _krb5_key_data
*dkey
;
1413 struct _krb5_encryption_type
*et
= crypto
->et
;
1414 krb5_crypto_iov
*tiv
, *hiv
;
1416 if(!derived_crypto(context
, crypto
)) {
1417 krb5_clear_error_message(context
);
1418 return KRB5_CRYPTO_INTERNAL
;
1421 headersz
= et
->confoundersize
;
1423 hiv
= find_iv(data
, num_data
, KRB5_CRYPTO_TYPE_HEADER
);
1424 if (hiv
== NULL
|| hiv
->data
.length
!= headersz
)
1425 return KRB5_BAD_MSIZE
;
1428 trailersz
= CHECKSUMSIZE(et
->keyed_checksum
);
1430 tiv
= find_iv(data
, num_data
, KRB5_CRYPTO_TYPE_TRAILER
);
1431 if (tiv
->data
.length
!= trailersz
)
1432 return KRB5_BAD_MSIZE
;
1434 /* Find length of data we will decrypt */
1437 for (i
= 0; i
< num_data
; i
++) {
1438 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
)
1440 len
+= data
[i
].data
.length
;
1443 if ((len
% et
->padsize
) != 0) {
1444 krb5_clear_error_message(context
);
1445 return KRB5_BAD_MSIZE
;
1448 /* XXX replace with EVP_Cipher */
1450 p
= q
= malloc(len
);
1454 memcpy(q
, hiv
->data
.data
, hiv
->data
.length
);
1455 q
+= hiv
->data
.length
;
1457 for (i
= 0; i
< num_data
; i
++) {
1458 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
)
1460 memcpy(q
, data
[i
].data
.data
, data
[i
].data
.length
);
1461 q
+= data
[i
].data
.length
;
1464 ret
= _get_derived_key(context
, crypto
, ENCRYPTION_USAGE(usage
), &dkey
);
1469 ret
= _key_schedule(context
, dkey
);
1475 ret
= (*et
->encrypt
)(context
, dkey
, p
, len
, 0, usage
, ivec
);
1481 /* copy data back to buffers */
1482 memcpy(hiv
->data
.data
, p
, hiv
->data
.length
);
1483 q
= p
+ hiv
->data
.length
;
1484 for (i
= 0; i
< num_data
; i
++) {
1485 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
)
1487 memcpy(data
[i
].data
.data
, q
, data
[i
].data
.length
);
1488 q
+= data
[i
].data
.length
;
1493 /* check signature */
1494 for (i
= 0; i
< num_data
; i
++) {
1495 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_SIGN_ONLY
)
1497 len
+= data
[i
].data
.length
;
1500 p
= q
= malloc(len
);
1504 memcpy(q
, hiv
->data
.data
, hiv
->data
.length
);
1505 q
+= hiv
->data
.length
;
1506 for (i
= 0; i
< num_data
; i
++) {
1507 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
&&
1508 data
[i
].flags
!= KRB5_CRYPTO_TYPE_SIGN_ONLY
)
1510 memcpy(q
, data
[i
].data
.data
, data
[i
].data
.length
);
1511 q
+= data
[i
].data
.length
;
1514 cksum
.checksum
.data
= tiv
->data
.data
;
1515 cksum
.checksum
.length
= tiv
->data
.length
;
1516 cksum
.cksumtype
= CHECKSUMTYPE(et
->keyed_checksum
);
1518 ret
= verify_checksum(context
,
1520 INTEGRITY_USAGE(usage
),
1529 * Create a Kerberos message checksum.
1531 * @param context Kerberos context
1532 * @param crypto Kerberos crypto context
1533 * @param usage Key usage for this buffer
1534 * @param data array of buffers to process
1535 * @param num_data length of array
1536 * @param type output data
1538 * @return Return an error code or 0.
1539 * @ingroup krb5_crypto
1542 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1543 krb5_create_checksum_iov(krb5_context context
,
1546 krb5_crypto_iov
*data
,
1547 unsigned int num_data
,
1548 krb5_cksumtype
*type
)
1551 krb5_crypto_iov
*civ
;
1552 krb5_error_code ret
;
1557 if(!derived_crypto(context
, crypto
)) {
1558 krb5_clear_error_message(context
);
1559 return KRB5_CRYPTO_INTERNAL
;
1562 civ
= find_iv(data
, num_data
, KRB5_CRYPTO_TYPE_CHECKSUM
);
1564 return KRB5_BAD_MSIZE
;
1567 for (i
= 0; i
< num_data
; i
++) {
1568 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
&&
1569 data
[i
].flags
!= KRB5_CRYPTO_TYPE_SIGN_ONLY
)
1571 len
+= data
[i
].data
.length
;
1574 p
= q
= malloc(len
);
1576 for (i
= 0; i
< num_data
; i
++) {
1577 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
&&
1578 data
[i
].flags
!= KRB5_CRYPTO_TYPE_SIGN_ONLY
)
1580 memcpy(q
, data
[i
].data
.data
, data
[i
].data
.length
);
1581 q
+= data
[i
].data
.length
;
1584 ret
= krb5_create_checksum(context
, crypto
, usage
, 0, p
, len
, &cksum
);
1590 *type
= cksum
.cksumtype
;
1592 if (cksum
.checksum
.length
> civ
->data
.length
) {
1593 krb5_set_error_message(context
, KRB5_BAD_MSIZE
,
1594 N_("Checksum larger then input buffer", ""));
1595 free_Checksum(&cksum
);
1596 return KRB5_BAD_MSIZE
;
1599 civ
->data
.length
= cksum
.checksum
.length
;
1600 memcpy(civ
->data
.data
, cksum
.checksum
.data
, civ
->data
.length
);
1601 free_Checksum(&cksum
);
1607 * Verify a Kerberos message checksum.
1609 * @param context Kerberos context
1610 * @param crypto Kerberos crypto context
1611 * @param usage Key usage for this buffer
1612 * @param data array of buffers to process
1613 * @param num_data length of array
1614 * @param type return checksum type if not NULL
1616 * @return Return an error code or 0.
1617 * @ingroup krb5_crypto
1620 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1621 krb5_verify_checksum_iov(krb5_context context
,
1624 krb5_crypto_iov
*data
,
1625 unsigned int num_data
,
1626 krb5_cksumtype
*type
)
1628 struct _krb5_encryption_type
*et
= crypto
->et
;
1630 krb5_crypto_iov
*civ
;
1631 krb5_error_code ret
;
1636 if(!derived_crypto(context
, crypto
)) {
1637 krb5_clear_error_message(context
);
1638 return KRB5_CRYPTO_INTERNAL
;
1641 civ
= find_iv(data
, num_data
, KRB5_CRYPTO_TYPE_CHECKSUM
);
1643 return KRB5_BAD_MSIZE
;
1646 for (i
= 0; i
< num_data
; i
++) {
1647 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
&&
1648 data
[i
].flags
!= KRB5_CRYPTO_TYPE_SIGN_ONLY
)
1650 len
+= data
[i
].data
.length
;
1653 p
= q
= malloc(len
);
1655 for (i
= 0; i
< num_data
; i
++) {
1656 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
&&
1657 data
[i
].flags
!= KRB5_CRYPTO_TYPE_SIGN_ONLY
)
1659 memcpy(q
, data
[i
].data
.data
, data
[i
].data
.length
);
1660 q
+= data
[i
].data
.length
;
1663 cksum
.cksumtype
= CHECKSUMTYPE(et
->keyed_checksum
);
1664 cksum
.checksum
.length
= civ
->data
.length
;
1665 cksum
.checksum
.data
= civ
->data
.data
;
1667 ret
= krb5_verify_checksum(context
, crypto
, usage
, p
, len
, &cksum
);
1670 if (ret
== 0 && type
)
1671 *type
= cksum
.cksumtype
;
1677 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1678 krb5_crypto_length(krb5_context context
,
1683 if (!derived_crypto(context
, crypto
)) {
1684 krb5_set_error_message(context
, EINVAL
, "not a derived crypto");
1689 case KRB5_CRYPTO_TYPE_EMPTY
:
1692 case KRB5_CRYPTO_TYPE_HEADER
:
1693 *len
= crypto
->et
->blocksize
;
1695 case KRB5_CRYPTO_TYPE_DATA
:
1696 case KRB5_CRYPTO_TYPE_SIGN_ONLY
:
1697 /* len must already been filled in */
1699 case KRB5_CRYPTO_TYPE_PADDING
:
1700 if (crypto
->et
->padsize
> 1)
1701 *len
= crypto
->et
->padsize
;
1705 case KRB5_CRYPTO_TYPE_TRAILER
:
1706 *len
= CHECKSUMSIZE(crypto
->et
->keyed_checksum
);
1708 case KRB5_CRYPTO_TYPE_CHECKSUM
:
1709 if (crypto
->et
->keyed_checksum
)
1710 *len
= CHECKSUMSIZE(crypto
->et
->keyed_checksum
);
1712 *len
= CHECKSUMSIZE(crypto
->et
->checksum
);
1715 krb5_set_error_message(context
, EINVAL
,
1716 "%d not a supported type", type
);
1721 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1722 krb5_crypto_length_iov(krb5_context context
,
1724 krb5_crypto_iov
*data
,
1725 unsigned int num_data
)
1727 krb5_error_code ret
;
1730 for (i
= 0; i
< num_data
; i
++) {
1731 ret
= krb5_crypto_length(context
, crypto
,
1733 &data
[i
].data
.length
);
1741 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1742 krb5_encrypt_ivec(krb5_context context
,
1750 if(derived_crypto(context
, crypto
))
1751 return encrypt_internal_derived(context
, crypto
, usage
,
1752 data
, len
, result
, ivec
);
1753 else if (special_crypto(context
, crypto
))
1754 return encrypt_internal_special (context
, crypto
, usage
,
1755 data
, len
, result
, ivec
);
1757 return encrypt_internal(context
, crypto
, data
, len
, result
, ivec
);
1760 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1761 krb5_encrypt(krb5_context context
,
1768 return krb5_encrypt_ivec(context
, crypto
, usage
, data
, len
, result
, NULL
);
1771 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1772 krb5_encrypt_EncryptedData(krb5_context context
,
1778 EncryptedData
*result
)
1780 result
->etype
= CRYPTO_ETYPE(crypto
);
1782 ALLOC(result
->kvno
, 1);
1783 *result
->kvno
= kvno
;
1785 result
->kvno
= NULL
;
1786 return krb5_encrypt(context
, crypto
, usage
, data
, len
, &result
->cipher
);
1789 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1790 krb5_decrypt_ivec(krb5_context context
,
1798 if(derived_crypto(context
, crypto
))
1799 return decrypt_internal_derived(context
, crypto
, usage
,
1800 data
, len
, result
, ivec
);
1801 else if (special_crypto (context
, crypto
))
1802 return decrypt_internal_special(context
, crypto
, usage
,
1803 data
, len
, result
, ivec
);
1805 return decrypt_internal(context
, crypto
, data
, len
, result
, ivec
);
1808 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1809 krb5_decrypt(krb5_context context
,
1816 return krb5_decrypt_ivec (context
, crypto
, usage
, data
, len
, result
,
1820 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1821 krb5_decrypt_EncryptedData(krb5_context context
,
1824 const EncryptedData
*e
,
1827 return krb5_decrypt(context
, crypto
, usage
,
1828 e
->cipher
.data
, e
->cipher
.length
, result
);
1831 /************************************************************
1833 ************************************************************/
1836 _krb5_derive_key(krb5_context context
,
1837 struct _krb5_encryption_type
*et
,
1838 struct _krb5_key_data
*key
,
1839 const void *constant
,
1842 unsigned char *k
= NULL
;
1843 unsigned int nblocks
= 0, i
;
1844 krb5_error_code ret
= 0;
1845 struct _krb5_key_type
*kt
= et
->keytype
;
1847 ret
= _key_schedule(context
, key
);
1850 if(et
->blocksize
* 8 < kt
->bits
|| len
!= et
->blocksize
) {
1851 nblocks
= (kt
->bits
+ et
->blocksize
* 8 - 1) / (et
->blocksize
* 8);
1852 k
= malloc(nblocks
* et
->blocksize
);
1855 krb5_set_error_message(context
, ret
, N_("malloc: out of memory", ""));
1858 ret
= _krb5_n_fold(constant
, len
, k
, et
->blocksize
);
1860 krb5_set_error_message(context
, ret
, N_("malloc: out of memory", ""));
1864 for(i
= 0; i
< nblocks
; i
++) {
1866 memcpy(k
+ i
* et
->blocksize
,
1867 k
+ (i
- 1) * et
->blocksize
,
1869 (*et
->encrypt
)(context
, key
, k
+ i
* et
->blocksize
, et
->blocksize
,
1873 /* this case is probably broken, but won't be run anyway */
1874 void *c
= malloc(len
);
1875 size_t res_len
= (kt
->bits
+ 7) / 8;
1877 if(len
!= 0 && c
== NULL
) {
1879 krb5_set_error_message(context
, ret
, N_("malloc: out of memory", ""));
1882 memcpy(c
, constant
, len
);
1883 (*et
->encrypt
)(context
, key
, c
, len
, 1, 0, NULL
);
1884 k
= malloc(res_len
);
1885 if(res_len
!= 0 && k
== NULL
) {
1888 krb5_set_error_message(context
, ret
, N_("malloc: out of memory", ""));
1891 ret
= _krb5_n_fold(c
, len
, k
, res_len
);
1894 krb5_set_error_message(context
, ret
, N_("malloc: out of memory", ""));
1899 /* XXX keytype dependent post-processing */
1901 case KRB5_ENCTYPE_OLD_DES3_CBC_SHA1
:
1902 _krb5_DES3_random_to_key(context
, key
->key
, k
, nblocks
* et
->blocksize
);
1904 case KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96
:
1905 case KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96
:
1906 memcpy(key
->key
->keyvalue
.data
, k
, key
->key
->keyvalue
.length
);
1909 ret
= KRB5_CRYPTO_INTERNAL
;
1910 krb5_set_error_message(context
, ret
,
1911 N_("derive_key() called with unknown keytype (%u)", ""),
1916 if (key
->schedule
) {
1917 free_key_schedule(context
, key
, et
);
1918 key
->schedule
= NULL
;
1921 memset(k
, 0, nblocks
* et
->blocksize
);
1927 static struct _krb5_key_data
*
1928 _new_derived_key(krb5_crypto crypto
, unsigned usage
)
1930 struct _krb5_key_usage
*d
= crypto
->key_usage
;
1931 d
= realloc(d
, (crypto
->num_key_usage
+ 1) * sizeof(*d
));
1934 crypto
->key_usage
= d
;
1935 d
+= crypto
->num_key_usage
++;
1936 memset(d
, 0, sizeof(*d
));
1941 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1942 krb5_derive_key(krb5_context context
,
1943 const krb5_keyblock
*key
,
1945 const void *constant
,
1946 size_t constant_len
,
1947 krb5_keyblock
**derived_key
)
1949 krb5_error_code ret
;
1950 struct _krb5_encryption_type
*et
;
1951 struct _krb5_key_data d
;
1953 *derived_key
= NULL
;
1955 et
= _krb5_find_enctype (etype
);
1957 krb5_set_error_message(context
, KRB5_PROG_ETYPE_NOSUPP
,
1958 N_("encryption type %d not supported", ""),
1960 return KRB5_PROG_ETYPE_NOSUPP
;
1963 ret
= krb5_copy_keyblock(context
, key
, &d
.key
);
1968 ret
= _krb5_derive_key(context
, et
, &d
, constant
, constant_len
);
1970 ret
= krb5_copy_keyblock(context
, d
.key
, derived_key
);
1971 _krb5_free_key_data(context
, &d
, et
);
1975 static krb5_error_code
1976 _get_derived_key(krb5_context context
,
1979 struct _krb5_key_data
**key
)
1982 struct _krb5_key_data
*d
;
1983 unsigned char constant
[5];
1985 for(i
= 0; i
< crypto
->num_key_usage
; i
++)
1986 if(crypto
->key_usage
[i
].usage
== usage
) {
1987 *key
= &crypto
->key_usage
[i
].key
;
1990 d
= _new_derived_key(crypto
, usage
);
1992 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
1995 krb5_copy_keyblock(context
, crypto
->key
.key
, &d
->key
);
1996 _krb5_put_int(constant
, usage
, 5);
1997 _krb5_derive_key(context
, crypto
->et
, d
, constant
, sizeof(constant
));
2003 * Create a crypto context used for all encryption and signature
2004 * operation. The encryption type to use is taken from the key, but
2005 * can be overridden with the enctype parameter. This can be useful
2006 * for encryptions types which is compatiable (DES for example).
2008 * To free the crypto context, use krb5_crypto_destroy().
2010 * @param context Kerberos context
2011 * @param key the key block information with all key data
2012 * @param etype the encryption type
2013 * @param crypto the resulting crypto context
2015 * @return Return an error code or 0.
2017 * @ingroup krb5_crypto
2020 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2021 krb5_crypto_init(krb5_context context
,
2022 const krb5_keyblock
*key
,
2024 krb5_crypto
*crypto
)
2026 krb5_error_code ret
;
2028 if(*crypto
== NULL
) {
2029 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
2032 if(etype
== ETYPE_NULL
)
2033 etype
= key
->keytype
;
2034 (*crypto
)->et
= _krb5_find_enctype(etype
);
2035 if((*crypto
)->et
== NULL
|| ((*crypto
)->et
->flags
& F_DISABLED
)) {
2038 krb5_set_error_message (context
, KRB5_PROG_ETYPE_NOSUPP
,
2039 N_("encryption type %d not supported", ""),
2041 return KRB5_PROG_ETYPE_NOSUPP
;
2043 if((*crypto
)->et
->keytype
->size
!= key
->keyvalue
.length
) {
2046 krb5_set_error_message (context
, KRB5_BAD_KEYSIZE
,
2047 "encryption key has bad length");
2048 return KRB5_BAD_KEYSIZE
;
2050 ret
= krb5_copy_keyblock(context
, key
, &(*crypto
)->key
.key
);
2056 (*crypto
)->key
.schedule
= NULL
;
2057 (*crypto
)->num_key_usage
= 0;
2058 (*crypto
)->key_usage
= NULL
;
2063 free_key_schedule(krb5_context context
,
2064 struct _krb5_key_data
*key
,
2065 struct _krb5_encryption_type
*et
)
2067 if (et
->keytype
->cleanup
)
2068 (*et
->keytype
->cleanup
)(context
, key
);
2069 memset(key
->schedule
->data
, 0, key
->schedule
->length
);
2070 krb5_free_data(context
, key
->schedule
);
2074 _krb5_free_key_data(krb5_context context
, struct _krb5_key_data
*key
,
2075 struct _krb5_encryption_type
*et
)
2077 krb5_free_keyblock(context
, key
->key
);
2079 free_key_schedule(context
, key
, et
);
2080 key
->schedule
= NULL
;
2085 free_key_usage(krb5_context context
, struct _krb5_key_usage
*ku
,
2086 struct _krb5_encryption_type
*et
)
2088 _krb5_free_key_data(context
, &ku
->key
, et
);
2092 * Free a crypto context created by krb5_crypto_init().
2094 * @param context Kerberos context
2095 * @param crypto crypto context to free
2097 * @return Return an error code or 0.
2099 * @ingroup krb5_crypto
2102 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2103 krb5_crypto_destroy(krb5_context context
,
2108 for(i
= 0; i
< crypto
->num_key_usage
; i
++)
2109 free_key_usage(context
, &crypto
->key_usage
[i
], crypto
->et
);
2110 free(crypto
->key_usage
);
2111 _krb5_free_key_data(context
, &crypto
->key
, crypto
->et
);
2117 * Return the blocksize used algorithm referenced by the crypto context
2119 * @param context Kerberos context
2120 * @param crypto crypto context to query
2121 * @param blocksize the resulting blocksize
2123 * @return Return an error code or 0.
2125 * @ingroup krb5_crypto
2128 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2129 krb5_crypto_getblocksize(krb5_context context
,
2133 *blocksize
= crypto
->et
->blocksize
;
2138 * Return the encryption type used by the crypto context
2140 * @param context Kerberos context
2141 * @param crypto crypto context to query
2142 * @param enctype the resulting encryption type
2144 * @return Return an error code or 0.
2146 * @ingroup krb5_crypto
2149 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2150 krb5_crypto_getenctype(krb5_context context
,
2152 krb5_enctype
*enctype
)
2154 *enctype
= crypto
->et
->type
;
2159 * Return the padding size used by the crypto context
2161 * @param context Kerberos context
2162 * @param crypto crypto context to query
2163 * @param padsize the return padding size
2165 * @return Return an error code or 0.
2167 * @ingroup krb5_crypto
2170 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2171 krb5_crypto_getpadsize(krb5_context context
,
2175 *padsize
= crypto
->et
->padsize
;
2180 * Return the confounder size used by the crypto context
2182 * @param context Kerberos context
2183 * @param crypto crypto context to query
2184 * @param confoundersize the returned confounder size
2186 * @return Return an error code or 0.
2188 * @ingroup krb5_crypto
2191 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2192 krb5_crypto_getconfoundersize(krb5_context context
,
2194 size_t *confoundersize
)
2196 *confoundersize
= crypto
->et
->confoundersize
;
2202 * Disable encryption type
2204 * @param context Kerberos 5 context
2205 * @param enctype encryption type to disable
2207 * @return Return an error code or 0.
2209 * @ingroup krb5_crypto
2212 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2213 krb5_enctype_disable(krb5_context context
,
2214 krb5_enctype enctype
)
2216 struct _krb5_encryption_type
*et
= _krb5_find_enctype(enctype
);
2219 krb5_set_error_message (context
, KRB5_PROG_ETYPE_NOSUPP
,
2220 N_("encryption type %d not supported", ""),
2222 return KRB5_PROG_ETYPE_NOSUPP
;
2224 et
->flags
|= F_DISABLED
;
2229 * Enable encryption type
2231 * @param context Kerberos 5 context
2232 * @param enctype encryption type to enable
2234 * @return Return an error code or 0.
2236 * @ingroup krb5_crypto
2239 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2240 krb5_enctype_enable(krb5_context context
,
2241 krb5_enctype enctype
)
2243 struct _krb5_encryption_type
*et
= _krb5_find_enctype(enctype
);
2246 krb5_set_error_message (context
, KRB5_PROG_ETYPE_NOSUPP
,
2247 N_("encryption type %d not supported", ""),
2249 return KRB5_PROG_ETYPE_NOSUPP
;
2251 et
->flags
&= ~F_DISABLED
;
2256 * Enable or disable all weak encryption types
2258 * @param context Kerberos 5 context
2259 * @param enable true to enable, false to disable
2261 * @return Return an error code or 0.
2263 * @ingroup krb5_crypto
2266 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2267 krb5_allow_weak_crypto(krb5_context context
,
2268 krb5_boolean enable
)
2272 for(i
= 0; i
< _krb5_num_etypes
; i
++)
2273 if(_krb5_etypes
[i
]->flags
& F_WEAK
) {
2275 _krb5_etypes
[i
]->flags
&= ~F_DISABLED
;
2277 _krb5_etypes
[i
]->flags
|= F_DISABLED
;
2283 wrapped_length (krb5_context context
,
2287 struct _krb5_encryption_type
*et
= crypto
->et
;
2288 size_t padsize
= et
->padsize
;
2289 size_t checksumsize
= CHECKSUMSIZE(et
->checksum
);
2292 res
= et
->confoundersize
+ checksumsize
+ data_len
;
2293 res
= (res
+ padsize
- 1) / padsize
* padsize
;
2298 wrapped_length_dervied (krb5_context context
,
2302 struct _krb5_encryption_type
*et
= crypto
->et
;
2303 size_t padsize
= et
->padsize
;
2306 res
= et
->confoundersize
+ data_len
;
2307 res
= (res
+ padsize
- 1) / padsize
* padsize
;
2308 if (et
->keyed_checksum
)
2309 res
+= et
->keyed_checksum
->checksumsize
;
2311 res
+= et
->checksum
->checksumsize
;
2316 * Return the size of an encrypted packet of length `data_len'
2319 KRB5_LIB_FUNCTION
size_t KRB5_LIB_CALL
2320 krb5_get_wrapped_length (krb5_context context
,
2324 if (derived_crypto (context
, crypto
))
2325 return wrapped_length_dervied (context
, crypto
, data_len
);
2327 return wrapped_length (context
, crypto
, data_len
);
2331 * Return the size of an encrypted packet of length `data_len'
2335 crypto_overhead (krb5_context context
,
2338 struct _krb5_encryption_type
*et
= crypto
->et
;
2341 res
= CHECKSUMSIZE(et
->checksum
);
2342 res
+= et
->confoundersize
;
2343 if (et
->padsize
> 1)
2349 crypto_overhead_dervied (krb5_context context
,
2352 struct _krb5_encryption_type
*et
= crypto
->et
;
2355 if (et
->keyed_checksum
)
2356 res
= CHECKSUMSIZE(et
->keyed_checksum
);
2358 res
= CHECKSUMSIZE(et
->checksum
);
2359 res
+= et
->confoundersize
;
2360 if (et
->padsize
> 1)
2365 KRB5_LIB_FUNCTION
size_t KRB5_LIB_CALL
2366 krb5_crypto_overhead (krb5_context context
, krb5_crypto crypto
)
2368 if (derived_crypto (context
, crypto
))
2369 return crypto_overhead_dervied (context
, crypto
);
2371 return crypto_overhead (context
, crypto
);
2375 * Converts the random bytestring to a protocol key according to
2376 * Kerberos crypto frame work. It may be assumed that all the bits of
2377 * the input string are equally random, even though the entropy
2378 * present in the random source may be limited.
2380 * @param context Kerberos 5 context
2381 * @param type the enctype resulting key will be of
2382 * @param data input random data to convert to a key
2383 * @param size size of input random data, at least krb5_enctype_keysize() long
2384 * @param key key, output key, free with krb5_free_keyblock_contents()
2386 * @return Return an error code or 0.
2388 * @ingroup krb5_crypto
2391 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2392 krb5_random_to_key(krb5_context context
,
2398 krb5_error_code ret
;
2399 struct _krb5_encryption_type
*et
= _krb5_find_enctype(type
);
2401 krb5_set_error_message(context
, KRB5_PROG_ETYPE_NOSUPP
,
2402 N_("encryption type %d not supported", ""),
2404 return KRB5_PROG_ETYPE_NOSUPP
;
2406 if ((et
->keytype
->bits
+ 7) / 8 > size
) {
2407 krb5_set_error_message(context
, KRB5_PROG_ETYPE_NOSUPP
,
2408 N_("encryption key %s needs %d bytes "
2409 "of random to make an encryption key "
2411 et
->name
, (int)et
->keytype
->size
);
2412 return KRB5_PROG_ETYPE_NOSUPP
;
2414 ret
= krb5_data_alloc(&key
->keyvalue
, et
->keytype
->size
);
2417 key
->keytype
= type
;
2418 if (et
->keytype
->random_to_key
)
2419 (*et
->keytype
->random_to_key
)(context
, key
, data
, size
);
2421 memcpy(key
->keyvalue
.data
, data
, et
->keytype
->size
);
2428 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2429 krb5_crypto_prf_length(krb5_context context
,
2433 struct _krb5_encryption_type
*et
= _krb5_find_enctype(type
);
2435 if(et
== NULL
|| et
->prf_length
== 0) {
2436 krb5_set_error_message(context
, KRB5_PROG_ETYPE_NOSUPP
,
2437 N_("encryption type %d not supported", ""),
2439 return KRB5_PROG_ETYPE_NOSUPP
;
2442 *length
= et
->prf_length
;
2446 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2447 krb5_crypto_prf(krb5_context context
,
2448 const krb5_crypto crypto
,
2449 const krb5_data
*input
,
2452 struct _krb5_encryption_type
*et
= crypto
->et
;
2454 krb5_data_zero(output
);
2456 if(et
->prf
== NULL
) {
2457 krb5_set_error_message(context
, KRB5_PROG_ETYPE_NOSUPP
,
2458 "kerberos prf for %s not supported",
2460 return KRB5_PROG_ETYPE_NOSUPP
;
2463 return (*et
->prf
)(context
, crypto
, input
, output
);
2466 static krb5_error_code
2467 krb5_crypto_prfplus(krb5_context context
,
2468 const krb5_crypto crypto
,
2469 const krb5_data
*input
,
2473 krb5_error_code ret
;
2475 unsigned char i
= 1;
2478 krb5_data_zero(&input2
);
2479 krb5_data_zero(output
);
2481 krb5_clear_error_message(context
);
2483 ret
= krb5_data_alloc(output
, length
);
2485 ret
= krb5_data_alloc(&input2
, input
->length
+ 1);
2488 krb5_clear_error_message(context
);
2490 memcpy(((unsigned char *)input2
.data
) + 1, input
->data
, input
->length
);
2497 ((unsigned char *)input2
.data
)[0] = i
++;
2499 ret
= krb5_crypto_prf(context
, crypto
, &input2
, &block
);
2503 if (block
.length
< length
) {
2504 memcpy(p
, block
.data
, block
.length
);
2505 length
-= block
.length
;
2507 memcpy(p
, block
.data
, length
);
2511 krb5_data_free(&block
);
2515 krb5_data_free(&input2
);
2517 krb5_data_free(output
);
2522 * The FX-CF2 key derivation function, used in FAST and preauth framework.
2524 * @param context Kerberos 5 context
2525 * @param crypto1 first key to combine
2526 * @param crypto2 second key to combine
2527 * @param pepper1 factor to combine with first key to garante uniqueness
2528 * @param pepper2 factor to combine with second key to garante uniqueness
2529 * @param enctype the encryption type of the resulting key
2530 * @param res allocated key, free with krb5_free_keyblock_contents()
2532 * @return Return an error code or 0.
2534 * @ingroup krb5_crypto
2537 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2538 krb5_crypto_fx_cf2(krb5_context context
,
2539 const krb5_crypto crypto1
,
2540 const krb5_crypto crypto2
,
2543 krb5_enctype enctype
,
2546 krb5_error_code ret
;
2550 memset(res
, 0, sizeof(*res
));
2552 ret
= krb5_enctype_keysize(context
, enctype
, &keysize
);
2556 ret
= krb5_data_alloc(&res
->keyvalue
, keysize
);
2559 ret
= krb5_crypto_prfplus(context
, crypto1
, pepper1
, keysize
, &os1
);
2562 ret
= krb5_crypto_prfplus(context
, crypto2
, pepper2
, keysize
, &os2
);
2566 res
->keytype
= enctype
;
2568 unsigned char *p1
= os1
.data
, *p2
= os2
.data
, *p3
= res
->keyvalue
.data
;
2569 for (i
= 0; i
< keysize
; i
++)
2570 p3
[i
] = p1
[i
] ^ p2
[i
];
2574 krb5_data_free(&res
->keyvalue
);
2575 krb5_data_free(&os1
);
2576 krb5_data_free(&os2
);
2583 #ifndef HEIMDAL_SMALLER
2586 * Deprecated: keytypes doesn't exists, they are really enctypes.
2588 * @ingroup krb5_deprecated
2591 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2592 krb5_keytype_to_enctypes (krb5_context context
,
2593 krb5_keytype keytype
,
2596 KRB5_DEPRECATED_FUNCTION("Use X instead")
2602 for (i
= _krb5_num_etypes
- 1; i
>= 0; --i
) {
2603 if (_krb5_etypes
[i
]->keytype
->type
== keytype
2604 && !(_krb5_etypes
[i
]->flags
& F_PSEUDO
)
2605 && krb5_enctype_valid(context
, _krb5_etypes
[i
]->type
) == 0)
2609 krb5_set_error_message(context
, KRB5_PROG_KEYTYPE_NOSUPP
,
2610 "Keytype have no mapping");
2611 return KRB5_PROG_KEYTYPE_NOSUPP
;
2614 ret
= malloc(n
* sizeof(*ret
));
2615 if (ret
== NULL
&& n
!= 0) {
2616 krb5_set_error_message(context
, ENOMEM
, "malloc: out of memory");
2620 for (i
= _krb5_num_etypes
- 1; i
>= 0; --i
) {
2621 if (_krb5_etypes
[i
]->keytype
->type
== keytype
2622 && !(_krb5_etypes
[i
]->flags
& F_PSEUDO
)
2623 && krb5_enctype_valid(context
, _krb5_etypes
[i
]->type
) == 0)
2624 ret
[n
++] = _krb5_etypes
[i
]->type
;
2632 * Deprecated: keytypes doesn't exists, they are really enctypes.
2634 * @ingroup krb5_deprecated
2637 /* if two enctypes have compatible keys */
2638 KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
2639 krb5_enctypes_compatible_keys(krb5_context context
,
2640 krb5_enctype etype1
,
2641 krb5_enctype etype2
)
2642 KRB5_DEPRECATED_FUNCTION("Use X instead")
2644 struct _krb5_encryption_type
*e1
= _krb5_find_enctype(etype1
);
2645 struct _krb5_encryption_type
*e2
= _krb5_find_enctype(etype2
);
2646 return e1
!= NULL
&& e2
!= NULL
&& e1
->keytype
== e2
->keytype
;
2649 #endif /* HEIMDAL_SMALLER */