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
*);
55 * Converts etype to a user readable string and sets as a side effect
56 * the krb5_error_message containing this string. Returns
57 * KRB5_PROG_ETYPE_NOSUPP in not the conversion of the etype failed in
58 * which case the error code of the etype convesion is returned.
61 static krb5_error_code
62 unsupported_enctype(krb5_context context
, krb5_enctype etype
)
67 ret
= krb5_enctype_to_string(context
, etype
, &name
);
71 krb5_set_error_message(context
, KRB5_PROG_ETYPE_NOSUPP
,
72 N_("Encryption type %s not supported", ""),
75 return KRB5_PROG_ETYPE_NOSUPP
;
82 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
83 krb5_enctype_keysize(krb5_context context
,
87 struct _krb5_encryption_type
*et
= _krb5_find_enctype(type
);
89 return unsupported_enctype (context
, type
);
91 *keysize
= et
->keytype
->size
;
95 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
96 krb5_enctype_keybits(krb5_context context
,
100 struct _krb5_encryption_type
*et
= _krb5_find_enctype(type
);
102 return unsupported_enctype (context
, type
);
104 *keybits
= et
->keytype
->bits
;
108 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
109 krb5_generate_random_keyblock(krb5_context context
,
114 struct _krb5_encryption_type
*et
= _krb5_find_enctype(type
);
116 return unsupported_enctype (context
, type
);
118 ret
= krb5_data_alloc(&key
->keyvalue
, et
->keytype
->size
);
122 if(et
->keytype
->random_key
)
123 (*et
->keytype
->random_key
)(context
, key
);
125 krb5_generate_random_block(key
->keyvalue
.data
,
126 key
->keyvalue
.length
);
130 static krb5_error_code
131 _key_schedule(krb5_context context
,
132 struct _krb5_key_data
*key
)
135 struct _krb5_encryption_type
*et
= _krb5_find_enctype(key
->key
->keytype
);
136 struct _krb5_key_type
*kt
;
139 return unsupported_enctype (context
,
145 if(kt
->schedule
== NULL
)
147 if (key
->schedule
!= NULL
)
149 ALLOC(key
->schedule
, 1);
150 if (key
->schedule
== NULL
)
151 return krb5_enomem(context
);
152 ret
= krb5_data_alloc(key
->schedule
, kt
->schedule_size
);
155 key
->schedule
= NULL
;
158 (*kt
->schedule
)(context
, kt
, key
);
162 /************************************************************
164 ************************************************************/
166 static krb5_error_code
167 SHA1_checksum(krb5_context context
,
168 struct _krb5_key_data
*key
,
174 if (EVP_Digest(data
, len
, C
->checksum
.data
, NULL
, EVP_sha1(), NULL
) != 1)
175 krb5_abortx(context
, "sha1 checksum failed");
179 /* HMAC according to RFC2104 */
180 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
181 _krb5_internal_hmac(krb5_context context
,
182 struct _krb5_checksum_type
*cm
,
186 struct _krb5_key_data
*keyblock
,
189 unsigned char *ipad
, *opad
;
194 ipad
= malloc(cm
->blocksize
+ len
);
197 opad
= malloc(cm
->blocksize
+ cm
->checksumsize
);
202 memset(ipad
, 0x36, cm
->blocksize
);
203 memset(opad
, 0x5c, cm
->blocksize
);
205 if(keyblock
->key
->keyvalue
.length
> cm
->blocksize
){
206 (*cm
->checksum
)(context
,
208 keyblock
->key
->keyvalue
.data
,
209 keyblock
->key
->keyvalue
.length
,
212 key
= result
->checksum
.data
;
213 key_len
= result
->checksum
.length
;
215 key
= keyblock
->key
->keyvalue
.data
;
216 key_len
= keyblock
->key
->keyvalue
.length
;
218 for(i
= 0; i
< key_len
; i
++){
222 memcpy(ipad
+ cm
->blocksize
, data
, len
);
223 (*cm
->checksum
)(context
, keyblock
, ipad
, cm
->blocksize
+ len
,
225 memcpy(opad
+ cm
->blocksize
, result
->checksum
.data
,
226 result
->checksum
.length
);
227 (*cm
->checksum
)(context
, keyblock
, opad
,
228 cm
->blocksize
+ cm
->checksumsize
, usage
, result
);
229 memset(ipad
, 0, cm
->blocksize
+ len
);
231 memset(opad
, 0, cm
->blocksize
+ cm
->checksumsize
);
237 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
238 krb5_hmac(krb5_context context
,
239 krb5_cksumtype cktype
,
246 struct _krb5_checksum_type
*c
= _krb5_find_checksum(cktype
);
247 struct _krb5_key_data kd
;
251 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
252 N_("checksum type %d not supported", ""),
254 return KRB5_PROG_SUMTYPE_NOSUPP
;
260 ret
= _krb5_internal_hmac(context
, c
, data
, len
, usage
, &kd
, result
);
263 krb5_free_data(context
, kd
.schedule
);
269 _krb5_SP_HMAC_SHA1_checksum(krb5_context context
,
270 struct _krb5_key_data
*key
,
276 struct _krb5_checksum_type
*c
= _krb5_find_checksum(CKSUMTYPE_SHA1
);
281 res
.checksum
.data
= sha1_data
;
282 res
.checksum
.length
= sizeof(sha1_data
);
284 ret
= _krb5_internal_hmac(context
, c
, data
, len
, usage
, key
, &res
);
286 krb5_abortx(context
, "hmac failed");
287 memcpy(result
->checksum
.data
, res
.checksum
.data
, result
->checksum
.length
);
291 struct _krb5_checksum_type _krb5_checksum_sha1
= {
301 KRB5_LIB_FUNCTION
struct _krb5_checksum_type
* KRB5_LIB_CALL
302 _krb5_find_checksum(krb5_cksumtype type
)
305 for(i
= 0; i
< _krb5_num_checksums
; i
++)
306 if(_krb5_checksum_types
[i
]->type
== type
)
307 return _krb5_checksum_types
[i
];
311 static krb5_error_code
312 get_checksum_key(krb5_context context
,
314 unsigned usage
, /* not krb5_key_usage */
315 struct _krb5_checksum_type
*ct
,
316 struct _krb5_key_data
**key
)
318 krb5_error_code ret
= 0;
320 if(ct
->flags
& F_DERIVED
)
321 ret
= _get_derived_key(context
, crypto
, usage
, key
);
322 else if(ct
->flags
& F_VARIANT
) {
325 *key
= _new_derived_key(crypto
, 0xff/* KRB5_KU_RFC1510_VARIANT */);
327 return krb5_enomem(context
);
328 ret
= krb5_copy_keyblock(context
, crypto
->key
.key
, &(*key
)->key
);
331 for(i
= 0; i
< (*key
)->key
->keyvalue
.length
; i
++)
332 ((unsigned char*)(*key
)->key
->keyvalue
.data
)[i
] ^= 0xF0;
337 ret
= _key_schedule(context
, *key
);
341 static krb5_error_code
342 create_checksum (krb5_context context
,
343 struct _krb5_checksum_type
*ct
,
351 struct _krb5_key_data
*dkey
;
354 if (ct
->flags
& F_DISABLED
) {
355 krb5_clear_error_message (context
);
356 return KRB5_PROG_SUMTYPE_NOSUPP
;
358 keyed_checksum
= (ct
->flags
& F_KEYED
) != 0;
359 if(keyed_checksum
&& crypto
== NULL
) {
360 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
361 N_("Checksum type %s is keyed but no "
362 "crypto context (key) was passed in", ""),
364 return KRB5_PROG_SUMTYPE_NOSUPP
; /* XXX */
367 ret
= get_checksum_key(context
, crypto
, usage
, ct
, &dkey
);
372 result
->cksumtype
= ct
->type
;
373 ret
= krb5_data_alloc(&result
->checksum
, ct
->checksumsize
);
376 return (*ct
->checksum
)(context
, dkey
, data
, len
, usage
, result
);
380 arcfour_checksum_p(struct _krb5_checksum_type
*ct
, krb5_crypto crypto
)
382 return (ct
->type
== CKSUMTYPE_HMAC_MD5
) &&
383 (crypto
->key
.key
->keytype
== KEYTYPE_ARCFOUR
);
386 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
387 krb5_create_checksum(krb5_context context
,
389 krb5_key_usage usage
,
395 struct _krb5_checksum_type
*ct
= NULL
;
398 /* type 0 -> pick from crypto */
400 ct
= _krb5_find_checksum(type
);
402 ct
= crypto
->et
->keyed_checksum
;
404 ct
= crypto
->et
->checksum
;
408 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
409 N_("checksum type %d not supported", ""),
411 return KRB5_PROG_SUMTYPE_NOSUPP
;
414 if (arcfour_checksum_p(ct
, crypto
)) {
416 _krb5_usage2arcfour(context
, &keyusage
);
418 keyusage
= CHECKSUM_USAGE(usage
);
420 return create_checksum(context
, ct
, crypto
, keyusage
,
424 static krb5_error_code
425 verify_checksum(krb5_context context
,
427 unsigned usage
, /* not krb5_key_usage */
433 struct _krb5_key_data
*dkey
;
436 struct _krb5_checksum_type
*ct
;
438 ct
= _krb5_find_checksum(cksum
->cksumtype
);
439 if (ct
== NULL
|| (ct
->flags
& F_DISABLED
)) {
440 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
441 N_("checksum type %d not supported", ""),
443 return KRB5_PROG_SUMTYPE_NOSUPP
;
445 if(ct
->checksumsize
!= cksum
->checksum
.length
) {
446 krb5_clear_error_message (context
);
447 krb5_set_error_message(context
, KRB5KRB_AP_ERR_BAD_INTEGRITY
,
448 N_("Decrypt integrity check failed for checksum type %s, "
449 "length was %u, expected %u", ""),
450 ct
->name
, (unsigned)cksum
->checksum
.length
,
451 (unsigned)ct
->checksumsize
);
453 return KRB5KRB_AP_ERR_BAD_INTEGRITY
; /* XXX */
455 keyed_checksum
= (ct
->flags
& F_KEYED
) != 0;
457 struct _krb5_checksum_type
*kct
;
458 if (crypto
== NULL
) {
459 krb5_set_error_message(context
, KRB5_PROG_SUMTYPE_NOSUPP
,
460 N_("Checksum type %s is keyed but no "
461 "crypto context (key) was passed in", ""),
463 return KRB5_PROG_SUMTYPE_NOSUPP
; /* XXX */
465 kct
= crypto
->et
->keyed_checksum
;
466 if (kct
== NULL
|| kct
->type
!= ct
->type
) {
467 krb5_set_error_message(context
, KRB5_PROG_SUMTYPE_NOSUPP
,
468 N_("Checksum type %s is keyed, but "
469 "the key type %s passed didnt have that checksum "
470 "type as the keyed type", ""),
471 ct
->name
, crypto
->et
->name
);
472 return KRB5_PROG_SUMTYPE_NOSUPP
; /* XXX */
475 ret
= get_checksum_key(context
, crypto
, usage
, ct
, &dkey
);
482 * If checksum have a verify function, lets use that instead of
483 * calling ->checksum and then compare result.
487 ret
= (*ct
->verify
)(context
, dkey
, data
, len
, usage
, cksum
);
489 krb5_set_error_message(context
, ret
,
490 N_("Decrypt integrity check failed for checksum "
491 "type %s, key type %s", ""),
492 ct
->name
, (crypto
!= NULL
)? crypto
->et
->name
: "(none)");
496 ret
= krb5_data_alloc (&c
.checksum
, ct
->checksumsize
);
500 ret
= (*ct
->checksum
)(context
, dkey
, data
, len
, usage
, &c
);
502 krb5_data_free(&c
.checksum
);
506 if(krb5_data_ct_cmp(&c
.checksum
, &cksum
->checksum
) != 0) {
507 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
508 krb5_set_error_message(context
, ret
,
509 N_("Decrypt integrity check failed for checksum "
510 "type %s, key type %s", ""),
511 ct
->name
, crypto
? crypto
->et
->name
: "(unkeyed)");
515 krb5_data_free (&c
.checksum
);
519 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
520 krb5_verify_checksum(krb5_context context
,
522 krb5_key_usage usage
,
527 struct _krb5_checksum_type
*ct
;
530 ct
= _krb5_find_checksum(cksum
->cksumtype
);
532 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
533 N_("checksum type %d not supported", ""),
535 return KRB5_PROG_SUMTYPE_NOSUPP
;
538 if (arcfour_checksum_p(ct
, crypto
)) {
540 _krb5_usage2arcfour(context
, &keyusage
);
542 keyusage
= CHECKSUM_USAGE(usage
);
544 return verify_checksum(context
, crypto
, keyusage
,
548 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
549 krb5_crypto_get_checksum_type(krb5_context context
,
551 krb5_cksumtype
*type
)
553 struct _krb5_checksum_type
*ct
= NULL
;
555 if (crypto
!= NULL
) {
556 ct
= crypto
->et
->keyed_checksum
;
558 ct
= crypto
->et
->checksum
;
562 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
563 N_("checksum type not found", ""));
564 return KRB5_PROG_SUMTYPE_NOSUPP
;
573 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
574 krb5_checksumsize(krb5_context context
,
578 struct _krb5_checksum_type
*ct
= _krb5_find_checksum(type
);
580 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
581 N_("checksum type %d not supported", ""),
583 return KRB5_PROG_SUMTYPE_NOSUPP
;
585 *size
= ct
->checksumsize
;
589 KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
590 krb5_checksum_is_keyed(krb5_context context
,
593 struct _krb5_checksum_type
*ct
= _krb5_find_checksum(type
);
596 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
597 N_("checksum type %d not supported", ""),
599 return KRB5_PROG_SUMTYPE_NOSUPP
;
601 return ct
->flags
& F_KEYED
;
604 KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
605 krb5_checksum_is_collision_proof(krb5_context context
,
608 struct _krb5_checksum_type
*ct
= _krb5_find_checksum(type
);
611 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
612 N_("checksum type %d not supported", ""),
614 return KRB5_PROG_SUMTYPE_NOSUPP
;
616 return ct
->flags
& F_CPROOF
;
619 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
620 krb5_checksum_disable(krb5_context context
,
623 struct _krb5_checksum_type
*ct
= _krb5_find_checksum(type
);
626 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
627 N_("checksum type %d not supported", ""),
629 return KRB5_PROG_SUMTYPE_NOSUPP
;
631 ct
->flags
|= F_DISABLED
;
635 /************************************************************
637 ************************************************************/
639 KRB5_LIB_FUNCTION
struct _krb5_encryption_type
* KRB5_LIB_CALL
640 _krb5_find_enctype(krb5_enctype type
)
643 for(i
= 0; i
< _krb5_num_etypes
; i
++)
644 if(_krb5_etypes
[i
]->type
== type
)
645 return _krb5_etypes
[i
];
650 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
651 krb5_enctype_to_string(krb5_context context
,
655 struct _krb5_encryption_type
*e
;
656 e
= _krb5_find_enctype(etype
);
658 krb5_set_error_message (context
, KRB5_PROG_ETYPE_NOSUPP
,
659 N_("encryption type %d not supported", ""),
662 return KRB5_PROG_ETYPE_NOSUPP
;
664 *string
= strdup(e
->name
);
666 return krb5_enomem(context
);
670 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
671 krb5_string_to_enctype(krb5_context context
,
676 for(i
= 0; i
< _krb5_num_etypes
; i
++) {
677 if(strcasecmp(_krb5_etypes
[i
]->name
, string
) == 0){
678 *etype
= _krb5_etypes
[i
]->type
;
681 if(_krb5_etypes
[i
]->alias
!= NULL
&&
682 strcasecmp(_krb5_etypes
[i
]->alias
, string
) == 0){
683 *etype
= _krb5_etypes
[i
]->type
;
687 krb5_set_error_message (context
, KRB5_PROG_ETYPE_NOSUPP
,
688 N_("encryption type %s not supported", ""),
690 return KRB5_PROG_ETYPE_NOSUPP
;
693 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
694 krb5_enctype_to_keytype(krb5_context context
,
696 krb5_keytype
*keytype
)
698 struct _krb5_encryption_type
*e
= _krb5_find_enctype(etype
);
700 return unsupported_enctype (context
, etype
);
702 *keytype
= e
->keytype
->type
; /* XXX */
707 * Check if a enctype is valid, return 0 if it is.
709 * @param context Kerberos context
710 * @param etype enctype to check if its valid or not
712 * @return Return an error code for an failure or 0 on success (enctype valid).
713 * @ingroup krb5_crypto
716 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
717 krb5_enctype_valid(krb5_context context
,
720 struct _krb5_encryption_type
*e
= _krb5_find_enctype(etype
);
721 if(e
&& (e
->flags
& F_DISABLED
) == 0)
724 return KRB5_PROG_ETYPE_NOSUPP
;
726 return unsupported_enctype (context
, etype
);
728 /* Must be (e->flags & F_DISABLED) */
729 krb5_set_error_message (context
, KRB5_PROG_ETYPE_NOSUPP
,
730 N_("encryption type %s is disabled", ""),
732 return KRB5_PROG_ETYPE_NOSUPP
;
736 * Return the coresponding encryption type for a checksum type.
738 * @param context Kerberos context
739 * @param ctype The checksum type to get the result enctype for
740 * @param etype The returned encryption, when the matching etype is
741 * not found, etype is set to ETYPE_NULL.
743 * @return Return an error code for an failure or 0 on success.
744 * @ingroup krb5_crypto
748 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
749 krb5_cksumtype_to_enctype(krb5_context context
,
750 krb5_cksumtype ctype
,
757 for(i
= 0; i
< _krb5_num_etypes
; i
++) {
758 if(_krb5_etypes
[i
]->keyed_checksum
&&
759 _krb5_etypes
[i
]->keyed_checksum
->type
== ctype
)
761 *etype
= _krb5_etypes
[i
]->type
;
766 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
767 N_("checksum type %d not supported", ""),
769 return KRB5_PROG_SUMTYPE_NOSUPP
;
773 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
774 krb5_cksumtype_valid(krb5_context context
,
775 krb5_cksumtype ctype
)
777 struct _krb5_checksum_type
*c
= _krb5_find_checksum(ctype
);
779 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
780 N_("checksum type %d not supported", ""),
782 return KRB5_PROG_SUMTYPE_NOSUPP
;
784 if (c
->flags
& F_DISABLED
) {
785 krb5_set_error_message (context
, KRB5_PROG_SUMTYPE_NOSUPP
,
786 N_("checksum type %s is disabled", ""),
788 return KRB5_PROG_SUMTYPE_NOSUPP
;
795 derived_crypto(krb5_context context
,
798 return (crypto
->et
->flags
& F_DERIVED
) != 0;
802 special_crypto(krb5_context context
,
805 return (crypto
->et
->flags
& F_SPECIAL
) != 0;
808 #define CHECKSUMSIZE(C) ((C)->checksumsize)
809 #define CHECKSUMTYPE(C) ((C)->type)
811 static krb5_error_code
812 encrypt_internal_derived(krb5_context context
,
820 size_t sz
, block_sz
, checksum_sz
, total_sz
;
822 unsigned char *p
, *q
;
824 struct _krb5_key_data
*dkey
;
825 const struct _krb5_encryption_type
*et
= crypto
->et
;
827 checksum_sz
= CHECKSUMSIZE(et
->keyed_checksum
);
829 sz
= et
->confoundersize
+ len
;
830 block_sz
= (sz
+ et
->padsize
- 1) &~ (et
->padsize
- 1); /* pad */
831 total_sz
= block_sz
+ checksum_sz
;
832 p
= calloc(1, total_sz
);
834 return krb5_enomem(context
);
837 krb5_generate_random_block(q
, et
->confoundersize
); /* XXX */
838 q
+= et
->confoundersize
;
839 memcpy(q
, data
, len
);
841 ret
= create_checksum(context
,
844 INTEGRITY_USAGE(usage
),
848 if(ret
== 0 && cksum
.checksum
.length
!= checksum_sz
) {
849 free_Checksum (&cksum
);
850 krb5_clear_error_message (context
);
851 ret
= KRB5_CRYPTO_INTERNAL
;
855 memcpy(p
+ block_sz
, cksum
.checksum
.data
, cksum
.checksum
.length
);
856 free_Checksum (&cksum
);
857 ret
= _get_derived_key(context
, crypto
, ENCRYPTION_USAGE(usage
), &dkey
);
860 ret
= _key_schedule(context
, dkey
);
863 ret
= (*et
->encrypt
)(context
, dkey
, p
, block_sz
, 1, usage
, ivec
);
867 result
->length
= total_sz
;
870 memset(p
, 0, total_sz
);
876 static krb5_error_code
877 encrypt_internal(krb5_context context
,
884 size_t sz
, block_sz
, checksum_sz
;
886 unsigned char *p
, *q
;
888 const struct _krb5_encryption_type
*et
= crypto
->et
;
890 checksum_sz
= CHECKSUMSIZE(et
->checksum
);
892 sz
= et
->confoundersize
+ checksum_sz
+ len
;
893 block_sz
= (sz
+ et
->padsize
- 1) &~ (et
->padsize
- 1); /* pad */
894 p
= calloc(1, block_sz
);
896 return krb5_enomem(context
);
899 krb5_generate_random_block(q
, et
->confoundersize
); /* XXX */
900 q
+= et
->confoundersize
;
901 memset(q
, 0, checksum_sz
);
903 memcpy(q
, data
, len
);
905 ret
= create_checksum(context
,
912 if(ret
== 0 && cksum
.checksum
.length
!= checksum_sz
) {
913 krb5_clear_error_message (context
);
914 free_Checksum(&cksum
);
915 ret
= KRB5_CRYPTO_INTERNAL
;
919 memcpy(p
+ et
->confoundersize
, cksum
.checksum
.data
, cksum
.checksum
.length
);
920 free_Checksum(&cksum
);
921 ret
= _key_schedule(context
, &crypto
->key
);
924 ret
= (*et
->encrypt
)(context
, &crypto
->key
, p
, block_sz
, 1, 0, ivec
);
926 memset(p
, 0, block_sz
);
931 result
->length
= block_sz
;
934 memset(p
, 0, block_sz
);
939 static krb5_error_code
940 encrypt_internal_special(krb5_context context
,
948 struct _krb5_encryption_type
*et
= crypto
->et
;
949 size_t cksum_sz
= CHECKSUMSIZE(et
->checksum
);
950 size_t sz
= len
+ cksum_sz
+ et
->confoundersize
;
956 return krb5_enomem(context
);
958 memset (p
, 0, cksum_sz
);
960 krb5_generate_random_block(p
, et
->confoundersize
);
961 p
+= et
->confoundersize
;
962 memcpy (p
, data
, len
);
963 ret
= (*et
->encrypt
)(context
, &crypto
->key
, tmp
, sz
, TRUE
, usage
, ivec
);
974 static krb5_error_code
975 decrypt_internal_derived(krb5_context context
,
987 struct _krb5_key_data
*dkey
;
988 struct _krb5_encryption_type
*et
= crypto
->et
;
991 checksum_sz
= CHECKSUMSIZE(et
->keyed_checksum
);
992 if (len
< checksum_sz
+ et
->confoundersize
) {
993 krb5_set_error_message(context
, KRB5_BAD_MSIZE
,
994 N_("Encrypted data shorter then "
995 "checksum + confunder", ""));
996 return KRB5_BAD_MSIZE
;
999 if (((len
- checksum_sz
) % et
->padsize
) != 0) {
1000 krb5_clear_error_message(context
);
1001 return KRB5_BAD_MSIZE
;
1005 if (len
!= 0 && p
== NULL
)
1006 return krb5_enomem(context
);
1007 memcpy(p
, data
, len
);
1011 ret
= _get_derived_key(context
, crypto
, ENCRYPTION_USAGE(usage
), &dkey
);
1016 ret
= _key_schedule(context
, dkey
);
1021 ret
= (*et
->encrypt
)(context
, dkey
, p
, len
, 0, usage
, ivec
);
1027 cksum
.checksum
.data
= p
+ len
;
1028 cksum
.checksum
.length
= checksum_sz
;
1029 cksum
.cksumtype
= CHECKSUMTYPE(et
->keyed_checksum
);
1031 ret
= verify_checksum(context
,
1033 INTEGRITY_USAGE(usage
),
1041 l
= len
- et
->confoundersize
;
1042 memmove(p
, p
+ et
->confoundersize
, l
);
1043 result
->data
= realloc(p
, l
);
1044 if(result
->data
== NULL
&& l
!= 0) {
1046 return krb5_enomem(context
);
1052 static krb5_error_code
1053 decrypt_internal(krb5_context context
,
1060 krb5_error_code ret
;
1063 size_t checksum_sz
, l
;
1064 struct _krb5_encryption_type
*et
= crypto
->et
;
1066 if ((len
% et
->padsize
) != 0) {
1067 krb5_clear_error_message(context
);
1068 return KRB5_BAD_MSIZE
;
1070 checksum_sz
= CHECKSUMSIZE(et
->checksum
);
1071 if (len
< checksum_sz
+ et
->confoundersize
) {
1072 krb5_set_error_message(context
, KRB5_BAD_MSIZE
,
1073 N_("Encrypted data shorter then "
1074 "checksum + confunder", ""));
1075 return KRB5_BAD_MSIZE
;
1079 if (len
!= 0 && p
== NULL
)
1080 return krb5_enomem(context
);
1081 memcpy(p
, data
, len
);
1083 ret
= _key_schedule(context
, &crypto
->key
);
1088 ret
= (*et
->encrypt
)(context
, &crypto
->key
, p
, len
, 0, 0, ivec
);
1093 ret
= krb5_data_copy(&cksum
.checksum
, p
+ et
->confoundersize
, checksum_sz
);
1098 memset(p
+ et
->confoundersize
, 0, checksum_sz
);
1099 cksum
.cksumtype
= CHECKSUMTYPE(et
->checksum
);
1100 ret
= verify_checksum(context
, NULL
, 0, p
, len
, &cksum
);
1101 free_Checksum(&cksum
);
1106 l
= len
- et
->confoundersize
- checksum_sz
;
1107 memmove(p
, p
+ et
->confoundersize
+ checksum_sz
, l
);
1108 result
->data
= realloc(p
, l
);
1109 if(result
->data
== NULL
&& l
!= 0) {
1111 return krb5_enomem(context
);
1117 static krb5_error_code
1118 decrypt_internal_special(krb5_context context
,
1126 struct _krb5_encryption_type
*et
= crypto
->et
;
1127 size_t cksum_sz
= CHECKSUMSIZE(et
->checksum
);
1128 size_t sz
= len
- cksum_sz
- et
->confoundersize
;
1130 krb5_error_code ret
;
1132 if ((len
% et
->padsize
) != 0) {
1133 krb5_clear_error_message(context
);
1134 return KRB5_BAD_MSIZE
;
1136 if (len
< cksum_sz
+ et
->confoundersize
) {
1137 krb5_set_error_message(context
, KRB5_BAD_MSIZE
,
1138 N_("Encrypted data shorter then "
1139 "checksum + confunder", ""));
1140 return KRB5_BAD_MSIZE
;
1145 return krb5_enomem(context
);
1146 memcpy(p
, data
, len
);
1148 ret
= (*et
->encrypt
)(context
, &crypto
->key
, p
, len
, FALSE
, usage
, ivec
);
1154 memmove (p
, p
+ cksum_sz
+ et
->confoundersize
, sz
);
1155 result
->data
= realloc(p
, sz
);
1156 if(result
->data
== NULL
&& sz
!= 0) {
1158 return krb5_enomem(context
);
1160 result
->length
= sz
;
1164 static krb5_crypto_iov
*
1165 find_iv(krb5_crypto_iov
*data
, size_t num_data
, unsigned type
)
1168 for (i
= 0; i
< num_data
; i
++)
1169 if (data
[i
].flags
== type
)
1175 * Inline encrypt a kerberos message
1177 * @param context Kerberos context
1178 * @param crypto Kerberos crypto context
1179 * @param usage Key usage for this buffer
1180 * @param data array of buffers to process
1181 * @param num_data length of array
1182 * @param ivec initial cbc/cts vector
1184 * @return Return an error code or 0.
1185 * @ingroup krb5_crypto
1187 * Kerberos encrypted data look like this:
1189 * 1. KRB5_CRYPTO_TYPE_HEADER
1190 * 2. array [1,...] KRB5_CRYPTO_TYPE_DATA and array [0,...]
1191 * KRB5_CRYPTO_TYPE_SIGN_ONLY in any order, however the receiver
1192 * have to aware of the order. KRB5_CRYPTO_TYPE_SIGN_ONLY is
1193 * commonly used headers and trailers.
1194 * 3. KRB5_CRYPTO_TYPE_PADDING, at least on padsize long if padsize > 1
1195 * 4. KRB5_CRYPTO_TYPE_TRAILER
1198 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1199 krb5_encrypt_iov_ivec(krb5_context context
,
1202 krb5_crypto_iov
*data
,
1206 size_t headersz
, trailersz
, len
;
1208 size_t sz
, block_sz
, pad_sz
;
1210 unsigned char *p
, *q
;
1211 krb5_error_code ret
;
1212 struct _krb5_key_data
*dkey
;
1213 const struct _krb5_encryption_type
*et
= crypto
->et
;
1214 krb5_crypto_iov
*tiv
, *piv
, *hiv
;
1217 krb5_clear_error_message(context
);
1218 return KRB5_CRYPTO_INTERNAL
;
1221 if(!derived_crypto(context
, crypto
)) {
1222 krb5_clear_error_message(context
);
1223 return KRB5_CRYPTO_INTERNAL
;
1226 headersz
= et
->confoundersize
;
1227 trailersz
= CHECKSUMSIZE(et
->keyed_checksum
);
1229 for (len
= 0, i
= 0; i
< num_data
; i
++) {
1230 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
)
1232 len
+= data
[i
].data
.length
;
1235 sz
= headersz
+ len
;
1236 block_sz
= (sz
+ et
->padsize
- 1) &~ (et
->padsize
- 1); /* pad */
1238 pad_sz
= block_sz
- sz
;
1242 hiv
= find_iv(data
, num_data
, KRB5_CRYPTO_TYPE_HEADER
);
1243 if (hiv
== NULL
|| hiv
->data
.length
!= headersz
)
1244 return KRB5_BAD_MSIZE
;
1246 krb5_generate_random_block(hiv
->data
.data
, hiv
->data
.length
);
1249 piv
= find_iv(data
, num_data
, KRB5_CRYPTO_TYPE_PADDING
);
1250 /* its ok to have no TYPE_PADDING if there is no padding */
1251 if (piv
== NULL
&& pad_sz
!= 0)
1252 return KRB5_BAD_MSIZE
;
1254 if (piv
->data
.length
< pad_sz
)
1255 return KRB5_BAD_MSIZE
;
1256 piv
->data
.length
= pad_sz
;
1258 memset(piv
->data
.data
, pad_sz
, pad_sz
);
1264 tiv
= find_iv(data
, num_data
, KRB5_CRYPTO_TYPE_TRAILER
);
1265 if (tiv
== NULL
|| tiv
->data
.length
!= trailersz
)
1266 return KRB5_BAD_MSIZE
;
1269 * XXX replace with EVP_Sign? at least make create_checksum an iov
1271 * XXX CTS EVP is broken, can't handle multi buffers :(
1275 for (i
= 0; i
< num_data
; i
++) {
1276 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_SIGN_ONLY
)
1278 len
+= data
[i
].data
.length
;
1281 p
= q
= malloc(len
);
1283 memcpy(q
, hiv
->data
.data
, hiv
->data
.length
);
1284 q
+= hiv
->data
.length
;
1285 for (i
= 0; i
< num_data
; i
++) {
1286 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
&&
1287 data
[i
].flags
!= KRB5_CRYPTO_TYPE_SIGN_ONLY
)
1289 memcpy(q
, data
[i
].data
.data
, data
[i
].data
.length
);
1290 q
+= data
[i
].data
.length
;
1293 memset(q
, 0, piv
->data
.length
);
1295 ret
= create_checksum(context
,
1298 INTEGRITY_USAGE(usage
),
1303 if(ret
== 0 && cksum
.checksum
.length
!= trailersz
) {
1304 free_Checksum (&cksum
);
1305 krb5_clear_error_message (context
);
1306 ret
= KRB5_CRYPTO_INTERNAL
;
1311 /* save cksum at end */
1312 memcpy(tiv
->data
.data
, cksum
.checksum
.data
, cksum
.checksum
.length
);
1313 free_Checksum (&cksum
);
1315 /* XXX replace with EVP_Cipher */
1316 p
= q
= malloc(block_sz
);
1320 memcpy(q
, hiv
->data
.data
, hiv
->data
.length
);
1321 q
+= hiv
->data
.length
;
1323 for (i
= 0; i
< num_data
; i
++) {
1324 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
)
1326 memcpy(q
, data
[i
].data
.data
, data
[i
].data
.length
);
1327 q
+= data
[i
].data
.length
;
1330 memset(q
, 0, piv
->data
.length
);
1333 ret
= _get_derived_key(context
, crypto
, ENCRYPTION_USAGE(usage
), &dkey
);
1338 ret
= _key_schedule(context
, dkey
);
1344 ret
= (*et
->encrypt
)(context
, dkey
, p
, block_sz
, 1, usage
, ivec
);
1350 /* now copy data back to buffers */
1353 memcpy(hiv
->data
.data
, q
, hiv
->data
.length
);
1354 q
+= hiv
->data
.length
;
1356 for (i
= 0; i
< num_data
; i
++) {
1357 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
)
1359 memcpy(data
[i
].data
.data
, q
, data
[i
].data
.length
);
1360 q
+= data
[i
].data
.length
;
1363 memcpy(piv
->data
.data
, q
, pad_sz
);
1371 * Inline decrypt a Kerberos message.
1373 * @param context Kerberos context
1374 * @param crypto Kerberos crypto context
1375 * @param usage Key usage for this buffer
1376 * @param data array of buffers to process
1377 * @param num_data length of array
1378 * @param ivec initial cbc/cts vector
1380 * @return Return an error code or 0.
1381 * @ingroup krb5_crypto
1383 * 1. KRB5_CRYPTO_TYPE_HEADER
1384 * 2. one KRB5_CRYPTO_TYPE_DATA and array [0,...] of KRB5_CRYPTO_TYPE_SIGN_ONLY in
1385 * any order, however the receiver have to aware of the
1386 * order. KRB5_CRYPTO_TYPE_SIGN_ONLY is commonly used unencrypoted
1387 * protocol headers and trailers. The output data will be of same
1388 * size as the input data or shorter.
1391 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1392 krb5_decrypt_iov_ivec(krb5_context context
,
1395 krb5_crypto_iov
*data
,
1396 unsigned int num_data
,
1400 size_t headersz
, trailersz
, len
;
1402 unsigned char *p
, *q
;
1403 krb5_error_code ret
;
1404 struct _krb5_key_data
*dkey
;
1405 struct _krb5_encryption_type
*et
= crypto
->et
;
1406 krb5_crypto_iov
*tiv
, *hiv
;
1408 if(!derived_crypto(context
, crypto
)) {
1409 krb5_clear_error_message(context
);
1410 return KRB5_CRYPTO_INTERNAL
;
1413 headersz
= et
->confoundersize
;
1415 hiv
= find_iv(data
, num_data
, KRB5_CRYPTO_TYPE_HEADER
);
1416 if (hiv
== NULL
|| hiv
->data
.length
!= headersz
)
1417 return KRB5_BAD_MSIZE
;
1420 trailersz
= CHECKSUMSIZE(et
->keyed_checksum
);
1422 tiv
= find_iv(data
, num_data
, KRB5_CRYPTO_TYPE_TRAILER
);
1423 if (tiv
->data
.length
!= trailersz
)
1424 return KRB5_BAD_MSIZE
;
1426 /* Find length of data we will decrypt */
1429 for (i
= 0; i
< num_data
; i
++) {
1430 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
)
1432 len
+= data
[i
].data
.length
;
1435 if ((len
% et
->padsize
) != 0) {
1436 krb5_clear_error_message(context
);
1437 return KRB5_BAD_MSIZE
;
1440 /* XXX replace with EVP_Cipher */
1442 p
= q
= malloc(len
);
1446 memcpy(q
, hiv
->data
.data
, hiv
->data
.length
);
1447 q
+= hiv
->data
.length
;
1449 for (i
= 0; i
< num_data
; i
++) {
1450 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
)
1452 memcpy(q
, data
[i
].data
.data
, data
[i
].data
.length
);
1453 q
+= data
[i
].data
.length
;
1456 ret
= _get_derived_key(context
, crypto
, ENCRYPTION_USAGE(usage
), &dkey
);
1461 ret
= _key_schedule(context
, dkey
);
1467 ret
= (*et
->encrypt
)(context
, dkey
, p
, len
, 0, usage
, ivec
);
1473 /* copy data back to buffers */
1474 memcpy(hiv
->data
.data
, p
, hiv
->data
.length
);
1475 q
= p
+ hiv
->data
.length
;
1476 for (i
= 0; i
< num_data
; i
++) {
1477 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
)
1479 memcpy(data
[i
].data
.data
, q
, data
[i
].data
.length
);
1480 q
+= data
[i
].data
.length
;
1485 /* check signature */
1486 for (i
= 0; i
< num_data
; i
++) {
1487 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_SIGN_ONLY
)
1489 len
+= data
[i
].data
.length
;
1492 p
= q
= malloc(len
);
1496 memcpy(q
, hiv
->data
.data
, hiv
->data
.length
);
1497 q
+= hiv
->data
.length
;
1498 for (i
= 0; i
< num_data
; i
++) {
1499 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
&&
1500 data
[i
].flags
!= KRB5_CRYPTO_TYPE_SIGN_ONLY
)
1502 memcpy(q
, data
[i
].data
.data
, data
[i
].data
.length
);
1503 q
+= data
[i
].data
.length
;
1506 cksum
.checksum
.data
= tiv
->data
.data
;
1507 cksum
.checksum
.length
= tiv
->data
.length
;
1508 cksum
.cksumtype
= CHECKSUMTYPE(et
->keyed_checksum
);
1510 ret
= verify_checksum(context
,
1512 INTEGRITY_USAGE(usage
),
1521 * Create a Kerberos message checksum.
1523 * @param context Kerberos context
1524 * @param crypto Kerberos crypto context
1525 * @param usage Key usage for this buffer
1526 * @param data array of buffers to process
1527 * @param num_data length of array
1528 * @param type output data
1530 * @return Return an error code or 0.
1531 * @ingroup krb5_crypto
1534 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1535 krb5_create_checksum_iov(krb5_context context
,
1538 krb5_crypto_iov
*data
,
1539 unsigned int num_data
,
1540 krb5_cksumtype
*type
)
1543 krb5_crypto_iov
*civ
;
1544 krb5_error_code ret
;
1549 if(!derived_crypto(context
, crypto
)) {
1550 krb5_clear_error_message(context
);
1551 return KRB5_CRYPTO_INTERNAL
;
1554 civ
= find_iv(data
, num_data
, KRB5_CRYPTO_TYPE_CHECKSUM
);
1556 return KRB5_BAD_MSIZE
;
1559 for (i
= 0; i
< num_data
; i
++) {
1560 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
&&
1561 data
[i
].flags
!= KRB5_CRYPTO_TYPE_SIGN_ONLY
)
1563 len
+= data
[i
].data
.length
;
1566 p
= q
= malloc(len
);
1568 for (i
= 0; i
< num_data
; i
++) {
1569 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
&&
1570 data
[i
].flags
!= KRB5_CRYPTO_TYPE_SIGN_ONLY
)
1572 memcpy(q
, data
[i
].data
.data
, data
[i
].data
.length
);
1573 q
+= data
[i
].data
.length
;
1576 ret
= krb5_create_checksum(context
, crypto
, usage
, 0, p
, len
, &cksum
);
1582 *type
= cksum
.cksumtype
;
1584 if (cksum
.checksum
.length
> civ
->data
.length
) {
1585 krb5_set_error_message(context
, KRB5_BAD_MSIZE
,
1586 N_("Checksum larger then input buffer", ""));
1587 free_Checksum(&cksum
);
1588 return KRB5_BAD_MSIZE
;
1591 civ
->data
.length
= cksum
.checksum
.length
;
1592 memcpy(civ
->data
.data
, cksum
.checksum
.data
, civ
->data
.length
);
1593 free_Checksum(&cksum
);
1599 * Verify a Kerberos message checksum.
1601 * @param context Kerberos context
1602 * @param crypto Kerberos crypto context
1603 * @param usage Key usage for this buffer
1604 * @param data array of buffers to process
1605 * @param num_data length of array
1606 * @param type return checksum type if not NULL
1608 * @return Return an error code or 0.
1609 * @ingroup krb5_crypto
1612 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1613 krb5_verify_checksum_iov(krb5_context context
,
1616 krb5_crypto_iov
*data
,
1617 unsigned int num_data
,
1618 krb5_cksumtype
*type
)
1620 struct _krb5_encryption_type
*et
= crypto
->et
;
1622 krb5_crypto_iov
*civ
;
1623 krb5_error_code ret
;
1628 if(!derived_crypto(context
, crypto
)) {
1629 krb5_clear_error_message(context
);
1630 return KRB5_CRYPTO_INTERNAL
;
1633 civ
= find_iv(data
, num_data
, KRB5_CRYPTO_TYPE_CHECKSUM
);
1635 return KRB5_BAD_MSIZE
;
1638 for (i
= 0; i
< num_data
; i
++) {
1639 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
&&
1640 data
[i
].flags
!= KRB5_CRYPTO_TYPE_SIGN_ONLY
)
1642 len
+= data
[i
].data
.length
;
1645 p
= q
= malloc(len
);
1647 for (i
= 0; i
< num_data
; i
++) {
1648 if (data
[i
].flags
!= KRB5_CRYPTO_TYPE_DATA
&&
1649 data
[i
].flags
!= KRB5_CRYPTO_TYPE_SIGN_ONLY
)
1651 memcpy(q
, data
[i
].data
.data
, data
[i
].data
.length
);
1652 q
+= data
[i
].data
.length
;
1655 cksum
.cksumtype
= CHECKSUMTYPE(et
->keyed_checksum
);
1656 cksum
.checksum
.length
= civ
->data
.length
;
1657 cksum
.checksum
.data
= civ
->data
.data
;
1659 ret
= krb5_verify_checksum(context
, crypto
, usage
, p
, len
, &cksum
);
1662 if (ret
== 0 && type
)
1663 *type
= cksum
.cksumtype
;
1669 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1670 krb5_crypto_length(krb5_context context
,
1675 if (!derived_crypto(context
, crypto
)) {
1676 krb5_set_error_message(context
, EINVAL
, "not a derived crypto");
1681 case KRB5_CRYPTO_TYPE_EMPTY
:
1684 case KRB5_CRYPTO_TYPE_HEADER
:
1685 *len
= crypto
->et
->blocksize
;
1687 case KRB5_CRYPTO_TYPE_DATA
:
1688 case KRB5_CRYPTO_TYPE_SIGN_ONLY
:
1689 /* len must already been filled in */
1691 case KRB5_CRYPTO_TYPE_PADDING
:
1692 if (crypto
->et
->padsize
> 1)
1693 *len
= crypto
->et
->padsize
;
1697 case KRB5_CRYPTO_TYPE_TRAILER
:
1698 *len
= CHECKSUMSIZE(crypto
->et
->keyed_checksum
);
1700 case KRB5_CRYPTO_TYPE_CHECKSUM
:
1701 if (crypto
->et
->keyed_checksum
)
1702 *len
= CHECKSUMSIZE(crypto
->et
->keyed_checksum
);
1704 *len
= CHECKSUMSIZE(crypto
->et
->checksum
);
1707 krb5_set_error_message(context
, EINVAL
,
1708 "%d not a supported type", type
);
1713 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1714 krb5_crypto_length_iov(krb5_context context
,
1716 krb5_crypto_iov
*data
,
1717 unsigned int num_data
)
1719 krb5_error_code ret
;
1722 for (i
= 0; i
< num_data
; i
++) {
1723 ret
= krb5_crypto_length(context
, crypto
,
1725 &data
[i
].data
.length
);
1733 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1734 krb5_encrypt_ivec(krb5_context context
,
1742 if(derived_crypto(context
, crypto
))
1743 return encrypt_internal_derived(context
, crypto
, usage
,
1744 data
, len
, result
, ivec
);
1745 else if (special_crypto(context
, crypto
))
1746 return encrypt_internal_special (context
, crypto
, usage
,
1747 data
, len
, result
, ivec
);
1749 return encrypt_internal(context
, crypto
, data
, len
, result
, ivec
);
1752 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1753 krb5_encrypt(krb5_context context
,
1760 return krb5_encrypt_ivec(context
, crypto
, usage
, data
, len
, result
, NULL
);
1763 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1764 krb5_encrypt_EncryptedData(krb5_context context
,
1770 EncryptedData
*result
)
1772 result
->etype
= CRYPTO_ETYPE(crypto
);
1774 ALLOC(result
->kvno
, 1);
1775 *result
->kvno
= kvno
;
1777 result
->kvno
= NULL
;
1778 return krb5_encrypt(context
, crypto
, usage
, data
, len
, &result
->cipher
);
1781 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1782 krb5_decrypt_ivec(krb5_context context
,
1790 if(derived_crypto(context
, crypto
))
1791 return decrypt_internal_derived(context
, crypto
, usage
,
1792 data
, len
, result
, ivec
);
1793 else if (special_crypto (context
, crypto
))
1794 return decrypt_internal_special(context
, crypto
, usage
,
1795 data
, len
, result
, ivec
);
1797 return decrypt_internal(context
, crypto
, data
, len
, result
, ivec
);
1800 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1801 krb5_decrypt(krb5_context context
,
1808 return krb5_decrypt_ivec (context
, crypto
, usage
, data
, len
, result
,
1812 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1813 krb5_decrypt_EncryptedData(krb5_context context
,
1816 const EncryptedData
*e
,
1819 return krb5_decrypt(context
, crypto
, usage
,
1820 e
->cipher
.data
, e
->cipher
.length
, result
);
1823 /************************************************************
1825 ************************************************************/
1827 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1828 _krb5_derive_key(krb5_context context
,
1829 struct _krb5_encryption_type
*et
,
1830 struct _krb5_key_data
*key
,
1831 const void *constant
,
1834 unsigned char *k
= NULL
;
1835 unsigned int nblocks
= 0, i
;
1836 krb5_error_code ret
= 0;
1837 struct _krb5_key_type
*kt
= et
->keytype
;
1839 ret
= _key_schedule(context
, key
);
1842 if(et
->blocksize
* 8 < kt
->bits
|| len
!= et
->blocksize
) {
1843 nblocks
= (kt
->bits
+ et
->blocksize
* 8 - 1) / (et
->blocksize
* 8);
1844 k
= malloc(nblocks
* et
->blocksize
);
1846 ret
= krb5_enomem(context
);
1849 ret
= _krb5_n_fold(constant
, len
, k
, et
->blocksize
);
1851 krb5_enomem(context
);
1855 for(i
= 0; i
< nblocks
; i
++) {
1857 memcpy(k
+ i
* et
->blocksize
,
1858 k
+ (i
- 1) * et
->blocksize
,
1860 (*et
->encrypt
)(context
, key
, k
+ i
* et
->blocksize
, et
->blocksize
,
1864 /* this case is probably broken, but won't be run anyway */
1865 void *c
= malloc(len
);
1866 size_t res_len
= (kt
->bits
+ 7) / 8;
1868 if(len
!= 0 && c
== NULL
) {
1869 ret
= krb5_enomem(context
);
1872 memcpy(c
, constant
, len
);
1873 (*et
->encrypt
)(context
, key
, c
, len
, 1, 0, NULL
);
1874 k
= malloc(res_len
);
1875 if(res_len
!= 0 && k
== NULL
) {
1877 ret
= krb5_enomem(context
);
1880 ret
= _krb5_n_fold(c
, len
, k
, res_len
);
1883 krb5_enomem(context
);
1888 /* XXX keytype dependent post-processing */
1890 case KRB5_ENCTYPE_OLD_DES3_CBC_SHA1
:
1891 _krb5_DES3_random_to_key(context
, key
->key
, k
, nblocks
* et
->blocksize
);
1893 case KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96
:
1894 case KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96
:
1895 memcpy(key
->key
->keyvalue
.data
, k
, key
->key
->keyvalue
.length
);
1898 ret
= KRB5_CRYPTO_INTERNAL
;
1899 krb5_set_error_message(context
, ret
,
1900 N_("derive_key() called with unknown keytype (%u)", ""),
1905 if (key
->schedule
) {
1906 free_key_schedule(context
, key
, et
);
1907 key
->schedule
= NULL
;
1910 memset(k
, 0, nblocks
* et
->blocksize
);
1916 static struct _krb5_key_data
*
1917 _new_derived_key(krb5_crypto crypto
, unsigned usage
)
1919 struct _krb5_key_usage
*d
= crypto
->key_usage
;
1920 d
= realloc(d
, (crypto
->num_key_usage
+ 1) * sizeof(*d
));
1923 crypto
->key_usage
= d
;
1924 d
+= crypto
->num_key_usage
++;
1925 memset(d
, 0, sizeof(*d
));
1930 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1931 krb5_derive_key(krb5_context context
,
1932 const krb5_keyblock
*key
,
1934 const void *constant
,
1935 size_t constant_len
,
1936 krb5_keyblock
**derived_key
)
1938 krb5_error_code ret
;
1939 struct _krb5_encryption_type
*et
;
1940 struct _krb5_key_data d
;
1942 *derived_key
= NULL
;
1944 et
= _krb5_find_enctype (etype
);
1946 return unsupported_enctype (context
, etype
);
1949 ret
= krb5_copy_keyblock(context
, key
, &d
.key
);
1954 ret
= _krb5_derive_key(context
, et
, &d
, constant
, constant_len
);
1956 ret
= krb5_copy_keyblock(context
, d
.key
, derived_key
);
1957 _krb5_free_key_data(context
, &d
, et
);
1961 static krb5_error_code
1962 _get_derived_key(krb5_context context
,
1965 struct _krb5_key_data
**key
)
1968 struct _krb5_key_data
*d
;
1969 unsigned char constant
[5];
1971 for(i
= 0; i
< crypto
->num_key_usage
; i
++)
1972 if(crypto
->key_usage
[i
].usage
== usage
) {
1973 *key
= &crypto
->key_usage
[i
].key
;
1976 d
= _new_derived_key(crypto
, usage
);
1978 return krb5_enomem(context
);
1979 krb5_copy_keyblock(context
, crypto
->key
.key
, &d
->key
);
1980 _krb5_put_int(constant
, usage
, 5);
1981 _krb5_derive_key(context
, crypto
->et
, d
, constant
, sizeof(constant
));
1987 * Create a crypto context used for all encryption and signature
1988 * operation. The encryption type to use is taken from the key, but
1989 * can be overridden with the enctype parameter. This can be useful
1990 * for encryptions types which is compatiable (DES for example).
1992 * To free the crypto context, use krb5_crypto_destroy().
1994 * @param context Kerberos context
1995 * @param key the key block information with all key data
1996 * @param etype the encryption type
1997 * @param crypto the resulting crypto context
1999 * @return Return an error code or 0.
2001 * @ingroup krb5_crypto
2004 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2005 krb5_crypto_init(krb5_context context
,
2006 const krb5_keyblock
*key
,
2008 krb5_crypto
*crypto
)
2010 krb5_error_code ret
;
2012 if (*crypto
== NULL
)
2013 return krb5_enomem(context
);
2014 if(etype
== (krb5_enctype
)ETYPE_NULL
)
2015 etype
= key
->keytype
;
2016 (*crypto
)->et
= _krb5_find_enctype(etype
);
2017 if((*crypto
)->et
== NULL
|| ((*crypto
)->et
->flags
& F_DISABLED
)) {
2020 return unsupported_enctype(context
, etype
);
2022 if((*crypto
)->et
->keytype
->size
!= key
->keyvalue
.length
) {
2025 krb5_set_error_message (context
, KRB5_BAD_KEYSIZE
,
2026 "encryption key has bad length");
2027 return KRB5_BAD_KEYSIZE
;
2029 ret
= krb5_copy_keyblock(context
, key
, &(*crypto
)->key
.key
);
2035 (*crypto
)->key
.schedule
= NULL
;
2036 (*crypto
)->num_key_usage
= 0;
2037 (*crypto
)->key_usage
= NULL
;
2042 free_key_schedule(krb5_context context
,
2043 struct _krb5_key_data
*key
,
2044 struct _krb5_encryption_type
*et
)
2046 if (et
->keytype
->cleanup
)
2047 (*et
->keytype
->cleanup
)(context
, key
);
2048 memset(key
->schedule
->data
, 0, key
->schedule
->length
);
2049 krb5_free_data(context
, key
->schedule
);
2052 KRB5_LIB_FUNCTION
void KRB5_LIB_CALL
2053 _krb5_free_key_data(krb5_context context
, struct _krb5_key_data
*key
,
2054 struct _krb5_encryption_type
*et
)
2056 krb5_free_keyblock(context
, key
->key
);
2058 free_key_schedule(context
, key
, et
);
2059 key
->schedule
= NULL
;
2064 free_key_usage(krb5_context context
, struct _krb5_key_usage
*ku
,
2065 struct _krb5_encryption_type
*et
)
2067 _krb5_free_key_data(context
, &ku
->key
, et
);
2071 * Free a crypto context created by krb5_crypto_init().
2073 * @param context Kerberos context
2074 * @param crypto crypto context to free
2076 * @return Return an error code or 0.
2078 * @ingroup krb5_crypto
2081 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2082 krb5_crypto_destroy(krb5_context context
,
2087 for(i
= 0; i
< crypto
->num_key_usage
; i
++)
2088 free_key_usage(context
, &crypto
->key_usage
[i
], crypto
->et
);
2089 free(crypto
->key_usage
);
2090 _krb5_free_key_data(context
, &crypto
->key
, crypto
->et
);
2096 * Return the blocksize used algorithm referenced by the crypto context
2098 * @param context Kerberos context
2099 * @param crypto crypto context to query
2100 * @param blocksize the resulting blocksize
2102 * @return Return an error code or 0.
2104 * @ingroup krb5_crypto
2107 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2108 krb5_crypto_getblocksize(krb5_context context
,
2112 *blocksize
= crypto
->et
->blocksize
;
2117 * Return the encryption type used by the crypto context
2119 * @param context Kerberos context
2120 * @param crypto crypto context to query
2121 * @param enctype the resulting encryption type
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_getenctype(krb5_context context
,
2131 krb5_enctype
*enctype
)
2133 *enctype
= crypto
->et
->type
;
2138 * Return the padding size used by the crypto context
2140 * @param context Kerberos context
2141 * @param crypto crypto context to query
2142 * @param padsize the return padding size
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_getpadsize(krb5_context context
,
2154 *padsize
= crypto
->et
->padsize
;
2159 * Return the confounder size used by the crypto context
2161 * @param context Kerberos context
2162 * @param crypto crypto context to query
2163 * @param confoundersize the returned confounder 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_getconfoundersize(krb5_context context
,
2173 size_t *confoundersize
)
2175 *confoundersize
= crypto
->et
->confoundersize
;
2181 * Disable encryption type
2183 * @param context Kerberos 5 context
2184 * @param enctype encryption type to disable
2186 * @return Return an error code or 0.
2188 * @ingroup krb5_crypto
2191 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2192 krb5_enctype_disable(krb5_context context
,
2193 krb5_enctype enctype
)
2195 struct _krb5_encryption_type
*et
= _krb5_find_enctype(enctype
);
2198 krb5_set_error_message (context
, KRB5_PROG_ETYPE_NOSUPP
,
2199 N_("encryption type %d not supported", ""),
2201 return KRB5_PROG_ETYPE_NOSUPP
;
2203 et
->flags
|= F_DISABLED
;
2208 * Enable encryption type
2210 * @param context Kerberos 5 context
2211 * @param enctype encryption type to enable
2213 * @return Return an error code or 0.
2215 * @ingroup krb5_crypto
2218 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2219 krb5_enctype_enable(krb5_context context
,
2220 krb5_enctype enctype
)
2222 struct _krb5_encryption_type
*et
= _krb5_find_enctype(enctype
);
2225 krb5_set_error_message (context
, KRB5_PROG_ETYPE_NOSUPP
,
2226 N_("encryption type %d not supported", ""),
2228 return KRB5_PROG_ETYPE_NOSUPP
;
2230 et
->flags
&= ~F_DISABLED
;
2235 * Enable or disable all weak encryption types
2237 * @param context Kerberos 5 context
2238 * @param enable true to enable, false to disable
2240 * @return Return an error code or 0.
2242 * @ingroup krb5_crypto
2245 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2246 krb5_allow_weak_crypto(krb5_context context
,
2247 krb5_boolean enable
)
2251 for(i
= 0; i
< _krb5_num_etypes
; i
++)
2252 if(_krb5_etypes
[i
]->flags
& F_WEAK
) {
2254 _krb5_etypes
[i
]->flags
&= ~F_DISABLED
;
2256 _krb5_etypes
[i
]->flags
|= F_DISABLED
;
2262 * Returns is the encryption is strong or weak
2264 * @param context Kerberos 5 context
2265 * @param enctype encryption type to probe
2267 * @return Returns true if encryption type is weak or is not supported.
2269 * @ingroup krb5_crypto
2272 KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
2273 krb5_is_enctype_weak(krb5_context context
, krb5_enctype enctype
)
2275 struct _krb5_encryption_type
*et
= _krb5_find_enctype(enctype
);
2276 if(et
== NULL
|| (et
->flags
& F_WEAK
))
2282 wrapped_length (krb5_context context
,
2286 struct _krb5_encryption_type
*et
= crypto
->et
;
2287 size_t padsize
= et
->padsize
;
2288 size_t checksumsize
= CHECKSUMSIZE(et
->checksum
);
2291 res
= et
->confoundersize
+ checksumsize
+ data_len
;
2292 res
= (res
+ padsize
- 1) / padsize
* padsize
;
2297 wrapped_length_dervied (krb5_context context
,
2301 struct _krb5_encryption_type
*et
= crypto
->et
;
2302 size_t padsize
= et
->padsize
;
2305 res
= et
->confoundersize
+ data_len
;
2306 res
= (res
+ padsize
- 1) / padsize
* padsize
;
2307 if (et
->keyed_checksum
)
2308 res
+= et
->keyed_checksum
->checksumsize
;
2310 res
+= et
->checksum
->checksumsize
;
2315 * Return the size of an encrypted packet of length `data_len'
2318 KRB5_LIB_FUNCTION
size_t KRB5_LIB_CALL
2319 krb5_get_wrapped_length (krb5_context context
,
2323 if (derived_crypto (context
, crypto
))
2324 return wrapped_length_dervied (context
, crypto
, data_len
);
2326 return wrapped_length (context
, crypto
, data_len
);
2330 * Return the size of an encrypted packet of length `data_len'
2334 crypto_overhead (krb5_context context
,
2337 struct _krb5_encryption_type
*et
= crypto
->et
;
2340 res
= CHECKSUMSIZE(et
->checksum
);
2341 res
+= et
->confoundersize
;
2342 if (et
->padsize
> 1)
2348 crypto_overhead_dervied (krb5_context context
,
2351 struct _krb5_encryption_type
*et
= crypto
->et
;
2354 if (et
->keyed_checksum
)
2355 res
= CHECKSUMSIZE(et
->keyed_checksum
);
2357 res
= CHECKSUMSIZE(et
->checksum
);
2358 res
+= et
->confoundersize
;
2359 if (et
->padsize
> 1)
2364 KRB5_LIB_FUNCTION
size_t KRB5_LIB_CALL
2365 krb5_crypto_overhead (krb5_context context
, krb5_crypto crypto
)
2367 if (derived_crypto (context
, crypto
))
2368 return crypto_overhead_dervied (context
, crypto
);
2370 return crypto_overhead (context
, crypto
);
2374 * Converts the random bytestring to a protocol key according to
2375 * Kerberos crypto frame work. It may be assumed that all the bits of
2376 * the input string are equally random, even though the entropy
2377 * present in the random source may be limited.
2379 * @param context Kerberos 5 context
2380 * @param type the enctype resulting key will be of
2381 * @param data input random data to convert to a key
2382 * @param size size of input random data, at least krb5_enctype_keysize() long
2383 * @param key key, output key, free with krb5_free_keyblock_contents()
2385 * @return Return an error code or 0.
2387 * @ingroup krb5_crypto
2390 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2391 krb5_random_to_key(krb5_context context
,
2397 krb5_error_code ret
;
2398 struct _krb5_encryption_type
*et
= _krb5_find_enctype(type
);
2400 krb5_set_error_message(context
, KRB5_PROG_ETYPE_NOSUPP
,
2401 N_("encryption type %d not supported", ""),
2403 return KRB5_PROG_ETYPE_NOSUPP
;
2405 if ((et
->keytype
->bits
+ 7) / 8 > size
) {
2406 krb5_set_error_message(context
, KRB5_PROG_ETYPE_NOSUPP
,
2407 N_("encryption key %s needs %d bytes "
2408 "of random to make an encryption key "
2410 et
->name
, (int)et
->keytype
->size
);
2411 return KRB5_PROG_ETYPE_NOSUPP
;
2413 ret
= krb5_data_alloc(&key
->keyvalue
, et
->keytype
->size
);
2416 key
->keytype
= type
;
2417 if (et
->keytype
->random_to_key
)
2418 (*et
->keytype
->random_to_key
)(context
, key
, data
, size
);
2420 memcpy(key
->keyvalue
.data
, data
, et
->keytype
->size
);
2427 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2428 krb5_crypto_prf_length(krb5_context context
,
2432 struct _krb5_encryption_type
*et
= _krb5_find_enctype(type
);
2434 if(et
== NULL
|| et
->prf_length
== 0) {
2435 krb5_set_error_message(context
, KRB5_PROG_ETYPE_NOSUPP
,
2436 N_("encryption type %d not supported", ""),
2438 return KRB5_PROG_ETYPE_NOSUPP
;
2441 *length
= et
->prf_length
;
2445 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2446 krb5_crypto_prf(krb5_context context
,
2447 const krb5_crypto crypto
,
2448 const krb5_data
*input
,
2451 struct _krb5_encryption_type
*et
= crypto
->et
;
2453 krb5_data_zero(output
);
2455 if(et
->prf
== NULL
) {
2456 krb5_set_error_message(context
, KRB5_PROG_ETYPE_NOSUPP
,
2457 "kerberos prf for %s not supported",
2459 return KRB5_PROG_ETYPE_NOSUPP
;
2462 return (*et
->prf
)(context
, crypto
, input
, output
);
2465 static krb5_error_code
2466 krb5_crypto_prfplus(krb5_context context
,
2467 const krb5_crypto crypto
,
2468 const krb5_data
*input
,
2472 krb5_error_code ret
;
2474 unsigned char i
= 1;
2477 krb5_data_zero(&input2
);
2478 krb5_data_zero(output
);
2480 krb5_clear_error_message(context
);
2482 ret
= krb5_data_alloc(output
, length
);
2484 ret
= krb5_data_alloc(&input2
, input
->length
+ 1);
2487 krb5_clear_error_message(context
);
2489 memcpy(((unsigned char *)input2
.data
) + 1, input
->data
, input
->length
);
2496 ((unsigned char *)input2
.data
)[0] = i
++;
2498 ret
= krb5_crypto_prf(context
, crypto
, &input2
, &block
);
2502 if (block
.length
< length
) {
2503 memcpy(p
, block
.data
, block
.length
);
2504 length
-= block
.length
;
2506 memcpy(p
, block
.data
, length
);
2510 krb5_data_free(&block
);
2514 krb5_data_free(&input2
);
2516 krb5_data_free(output
);
2521 * The FX-CF2 key derivation function, used in FAST and preauth framework.
2523 * @param context Kerberos 5 context
2524 * @param crypto1 first key to combine
2525 * @param crypto2 second key to combine
2526 * @param pepper1 factor to combine with first key to garante uniqueness
2527 * @param pepper2 factor to combine with second key to garante uniqueness
2528 * @param enctype the encryption type of the resulting key
2529 * @param res allocated key, free with krb5_free_keyblock_contents()
2531 * @return Return an error code or 0.
2533 * @ingroup krb5_crypto
2536 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2537 krb5_crypto_fx_cf2(krb5_context context
,
2538 const krb5_crypto crypto1
,
2539 const krb5_crypto crypto2
,
2542 krb5_enctype enctype
,
2545 krb5_error_code ret
;
2549 memset(res
, 0, sizeof(*res
));
2550 krb5_data_zero(&os1
);
2551 krb5_data_zero(&os2
);
2553 ret
= krb5_enctype_keysize(context
, enctype
, &keysize
);
2557 ret
= krb5_data_alloc(&res
->keyvalue
, keysize
);
2560 ret
= krb5_crypto_prfplus(context
, crypto1
, pepper1
, keysize
, &os1
);
2563 ret
= krb5_crypto_prfplus(context
, crypto2
, pepper2
, keysize
, &os2
);
2567 res
->keytype
= enctype
;
2569 unsigned char *p1
= os1
.data
, *p2
= os2
.data
, *p3
= res
->keyvalue
.data
;
2570 for (i
= 0; i
< keysize
; i
++)
2571 p3
[i
] = p1
[i
] ^ p2
[i
];
2575 krb5_data_free(&res
->keyvalue
);
2576 krb5_data_free(&os1
);
2577 krb5_data_free(&os2
);
2584 #ifndef HEIMDAL_SMALLER
2587 * Deprecated: keytypes doesn't exists, they are really enctypes.
2589 * @ingroup krb5_deprecated
2592 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2593 krb5_keytype_to_enctypes (krb5_context context
,
2594 krb5_keytype keytype
,
2597 KRB5_DEPRECATED_FUNCTION("Use X instead")
2603 for (i
= _krb5_num_etypes
- 1; i
>= 0; --i
) {
2604 if (_krb5_etypes
[i
]->keytype
->type
== keytype
2605 && !(_krb5_etypes
[i
]->flags
& F_PSEUDO
)
2606 && krb5_enctype_valid(context
, _krb5_etypes
[i
]->type
) == 0)
2610 krb5_set_error_message(context
, KRB5_PROG_KEYTYPE_NOSUPP
,
2611 "Keytype have no mapping");
2612 return KRB5_PROG_KEYTYPE_NOSUPP
;
2615 ret
= malloc(n
* sizeof(*ret
));
2616 if (ret
== NULL
&& n
!= 0)
2617 return krb5_enomem(context
);
2619 for (i
= _krb5_num_etypes
- 1; i
>= 0; --i
) {
2620 if (_krb5_etypes
[i
]->keytype
->type
== keytype
2621 && !(_krb5_etypes
[i
]->flags
& F_PSEUDO
)
2622 && krb5_enctype_valid(context
, _krb5_etypes
[i
]->type
) == 0)
2623 ret
[n
++] = _krb5_etypes
[i
]->type
;
2631 * Deprecated: keytypes doesn't exists, they are really enctypes.
2633 * @ingroup krb5_deprecated
2636 /* if two enctypes have compatible keys */
2637 KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
2638 krb5_enctypes_compatible_keys(krb5_context context
,
2639 krb5_enctype etype1
,
2640 krb5_enctype etype2
)
2641 KRB5_DEPRECATED_FUNCTION("Use X instead")
2643 struct _krb5_encryption_type
*e1
= _krb5_find_enctype(etype1
);
2644 struct _krb5_encryption_type
*e2
= _krb5_find_enctype(etype2
);
2645 return e1
!= NULL
&& e2
!= NULL
&& e1
->keytype
== e2
->keytype
;
2648 #endif /* HEIMDAL_SMALLER */