2 * Copyright (c) 1997 - 2005 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"
35 __RCSID("$Heimdal: crypto.c 22200 2007-12-07 13:48:01Z lha $"
36 "$NetBSD: crypto.c,v 1.14 2008/03/22 08:37:13 mlelstv Exp $");
40 static void krb5_crypto_debug(krb5_context
, int, size_t, krb5_keyblock
*);
54 struct krb5_crypto_data
{
55 struct encryption_type
*et
;
58 struct key_usage
*key_usage
;
61 #define CRYPTO_ETYPE(C) ((C)->et->type)
63 /* bits for `flags' below */
64 #define F_KEYED 1 /* checksum is keyed */
65 #define F_CPROOF 2 /* checksum is collision proof */
66 #define F_DERIVED 4 /* uses derived keys */
67 #define F_VARIANT 8 /* uses `variant' keys (6.4.3) */
68 #define F_PSEUDO 16 /* not a real protocol type */
69 #define F_SPECIAL 32 /* backwards */
70 #define F_DISABLED 64 /* enctype/checksum disabled */
75 krb5_error_code (*string_to_key
)(krb5_context
, krb5_enctype
, krb5_data
,
76 krb5_salt
, krb5_data
, krb5_keyblock
*);
80 krb5_keytype type
; /* XXX */
86 krb5_enctype best_etype
;
88 void (*random_key
)(krb5_context
, krb5_keyblock
*);
89 void (*schedule
)(krb5_context
, struct key_data
*);
90 struct salt_type
*string_to_key
;
91 void (*random_to_key
)(krb5_context
, krb5_keyblock
*, const void*, size_t);
94 struct checksum_type
{
100 void (*checksum
)(krb5_context context
,
101 struct key_data
*key
,
102 const void *buf
, size_t len
,
105 krb5_error_code (*verify
)(krb5_context context
,
106 struct key_data
*key
,
107 const void *buf
, size_t len
,
112 struct encryption_type
{
118 size_t confoundersize
;
119 struct key_type
*keytype
;
120 struct checksum_type
*checksum
;
121 struct checksum_type
*keyed_checksum
;
123 krb5_error_code (*encrypt
)(krb5_context context
,
124 struct key_data
*key
,
125 void *data
, size_t len
,
126 krb5_boolean encryptp
,
130 krb5_error_code (*prf
)(krb5_context
,
131 krb5_crypto
, const krb5_data
*, krb5_data
*);
134 #define ENCRYPTION_USAGE(U) (((U) << 8) | 0xAA)
135 #define INTEGRITY_USAGE(U) (((U) << 8) | 0x55)
136 #define CHECKSUM_USAGE(U) (((U) << 8) | 0x99)
138 static struct checksum_type
*_find_checksum(krb5_cksumtype type
);
139 static struct encryption_type
*_find_enctype(krb5_enctype type
);
140 static struct key_type
*_find_keytype(krb5_keytype type
);
141 static krb5_error_code
_get_derived_key(krb5_context
, krb5_crypto
,
142 unsigned, struct key_data
**);
143 static struct key_data
*_new_derived_key(krb5_crypto crypto
, unsigned usage
);
144 static krb5_error_code
derive_key(krb5_context context
,
145 struct encryption_type
*et
,
146 struct key_data
*key
,
147 const void *constant
,
149 static krb5_error_code
hmac(krb5_context context
,
150 struct checksum_type
*cm
,
154 struct key_data
*keyblock
,
156 static void free_key_data(krb5_context context
, struct key_data
*key
);
157 static krb5_error_code
usage2arcfour (krb5_context
, unsigned *);
158 static void xor (DES_cblock
*, const unsigned char *);
160 /************************************************************
162 ************************************************************/
164 static HEIMDAL_MUTEX crypto_mutex
= HEIMDAL_MUTEX_INITIALIZER
;
168 krb5_DES_random_key(krb5_context context
,
171 DES_cblock
*k
= key
->keyvalue
.data
;
173 krb5_generate_random_block(k
, sizeof(DES_cblock
));
174 DES_set_odd_parity(k
);
175 } while(DES_is_weak_key(k
));
179 krb5_DES_schedule(krb5_context context
,
180 struct key_data
*key
)
182 DES_set_key(key
->key
->keyvalue
.data
, key
->schedule
->data
);
185 #ifdef ENABLE_AFS_STRING_TO_KEY
187 /* This defines the Andrew string_to_key function. It accepts a password
188 * string as input and converts it via a one-way encryption algorithm to a DES
189 * encryption key. It is compatible with the original Andrew authentication
190 * service password database.
194 * Short passwords, i.e 8 characters or less.
197 krb5_DES_AFS3_CMU_string_to_key (krb5_data pw
,
201 char password
[8+1]; /* crypt is limited to 8 chars anyway */
204 for(i
= 0; i
< 8; i
++) {
205 char c
= ((i
< pw
.length
) ? ((char*)pw
.data
)[i
] : 0) ^
207 tolower(((unsigned char*)cell
.data
)[i
]) : 0);
208 password
[i
] = c
? c
: 'X';
212 memcpy(key
, crypt(password
, "p1") + 2, sizeof(DES_cblock
));
214 /* parity is inserted into the LSB so left shift each byte up one
215 bit. This allows ascii characters with a zero MSB to retain as
216 much significance as possible. */
217 for (i
= 0; i
< sizeof(DES_cblock
); i
++)
218 ((unsigned char*)key
)[i
] <<= 1;
219 DES_set_odd_parity (key
);
223 * Long passwords, i.e 9 characters or more.
226 krb5_DES_AFS3_Transarc_string_to_key (krb5_data pw
,
230 DES_key_schedule schedule
;
236 memcpy(password
, pw
.data
, min(pw
.length
, sizeof(password
)));
237 if(pw
.length
< sizeof(password
)) {
238 int len
= min(cell
.length
, sizeof(password
) - pw
.length
);
241 memcpy(password
+ pw
.length
, cell
.data
, len
);
242 for (i
= pw
.length
; i
< pw
.length
+ len
; ++i
)
243 password
[i
] = tolower((unsigned char)password
[i
]);
245 passlen
= min(sizeof(password
), pw
.length
+ cell
.length
);
246 memcpy(&ivec
, "kerberos", 8);
247 memcpy(&temp_key
, "kerberos", 8);
248 DES_set_odd_parity (&temp_key
);
249 DES_set_key (&temp_key
, &schedule
);
250 DES_cbc_cksum ((void*)password
, &ivec
, passlen
, &schedule
, &ivec
);
252 memcpy(&temp_key
, &ivec
, 8);
253 DES_set_odd_parity (&temp_key
);
254 DES_set_key (&temp_key
, &schedule
);
255 DES_cbc_cksum ((void*)password
, key
, passlen
, &schedule
, &ivec
);
256 memset(&schedule
, 0, sizeof(schedule
));
257 memset(&temp_key
, 0, sizeof(temp_key
));
258 memset(&ivec
, 0, sizeof(ivec
));
259 memset(password
, 0, sizeof(password
));
261 DES_set_odd_parity (key
);
264 static krb5_error_code
265 DES_AFS3_string_to_key(krb5_context context
,
266 krb5_enctype enctype
,
273 if(password
.length
> 8)
274 krb5_DES_AFS3_Transarc_string_to_key(password
, salt
.saltvalue
, &tmp
);
276 krb5_DES_AFS3_CMU_string_to_key(password
, salt
.saltvalue
, &tmp
);
277 key
->keytype
= enctype
;
278 krb5_data_copy(&key
->keyvalue
, tmp
, sizeof(tmp
));
279 memset(&key
, 0, sizeof(key
));
282 #endif /* ENABLE_AFS_STRING_TO_KEY */
285 DES_string_to_key_int(unsigned char *data
, size_t length
, DES_cblock
*key
)
287 DES_key_schedule schedule
;
292 unsigned char swap
[] = { 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
293 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf };
296 p
= (unsigned char*)key
;
297 for (i
= 0; i
< length
; i
++) {
298 unsigned char tmp
= data
[i
];
302 *--p
^= (swap
[tmp
& 0xf] << 4) | swap
[(tmp
& 0xf0) >> 4];
306 DES_set_odd_parity(key
);
307 if(DES_is_weak_key(key
))
309 DES_set_key(key
, &schedule
);
310 DES_cbc_cksum((void*)data
, key
, length
, &schedule
, key
);
311 memset(&schedule
, 0, sizeof(schedule
));
312 DES_set_odd_parity(key
);
313 if(DES_is_weak_key(key
))
317 static krb5_error_code
318 krb5_DES_string_to_key(krb5_context context
,
319 krb5_enctype enctype
,
329 #ifdef ENABLE_AFS_STRING_TO_KEY
330 if (opaque
.length
== 1) {
332 _krb5_get_int(opaque
.data
, &v
, 1);
334 return DES_AFS3_string_to_key(context
, enctype
, password
,
339 len
= password
.length
+ salt
.saltvalue
.length
;
341 if(len
> 0 && s
== NULL
) {
342 krb5_set_error_string(context
, "malloc: out of memory");
345 memcpy(s
, password
.data
, password
.length
);
346 memcpy(s
+ password
.length
, salt
.saltvalue
.data
, salt
.saltvalue
.length
);
347 DES_string_to_key_int(s
, len
, &tmp
);
348 key
->keytype
= enctype
;
349 krb5_data_copy(&key
->keyvalue
, tmp
, sizeof(tmp
));
350 memset(&tmp
, 0, sizeof(tmp
));
357 krb5_DES_random_to_key(krb5_context context
,
362 DES_cblock
*k
= key
->keyvalue
.data
;
363 memcpy(k
, data
, key
->keyvalue
.length
);
364 DES_set_odd_parity(k
);
365 if(DES_is_weak_key(k
))
366 xor(k
, (const unsigned char*)"\0\0\0\0\0\0\0\xf0");
374 DES3_random_key(krb5_context context
,
377 DES_cblock
*k
= key
->keyvalue
.data
;
379 krb5_generate_random_block(k
, 3 * sizeof(DES_cblock
));
380 DES_set_odd_parity(&k
[0]);
381 DES_set_odd_parity(&k
[1]);
382 DES_set_odd_parity(&k
[2]);
383 } while(DES_is_weak_key(&k
[0]) ||
384 DES_is_weak_key(&k
[1]) ||
385 DES_is_weak_key(&k
[2]));
389 DES3_schedule(krb5_context context
,
390 struct key_data
*key
)
392 DES_cblock
*k
= key
->key
->keyvalue
.data
;
393 DES_key_schedule
*s
= key
->schedule
->data
;
394 DES_set_key(&k
[0], &s
[0]);
395 DES_set_key(&k
[1], &s
[1]);
396 DES_set_key(&k
[2], &s
[2]);
400 * A = A xor B. A & B are 8 bytes.
404 xor (DES_cblock
*key
, const unsigned char *b
)
406 unsigned char *a
= (unsigned char*)key
;
417 static krb5_error_code
418 DES3_string_to_key(krb5_context context
,
419 krb5_enctype enctype
,
427 unsigned char tmp
[24];
431 len
= password
.length
+ salt
.saltvalue
.length
;
433 if(len
!= 0 && str
== NULL
) {
434 krb5_set_error_string(context
, "malloc: out of memory");
437 memcpy(str
, password
.data
, password
.length
);
438 memcpy(str
+ password
.length
, salt
.saltvalue
.data
, salt
.saltvalue
.length
);
441 DES_key_schedule s
[3];
444 ret
= _krb5_n_fold(str
, len
, tmp
, 24);
448 krb5_set_error_string(context
, "out of memory");
452 for(i
= 0; i
< 3; i
++){
453 memcpy(keys
+ i
, tmp
+ i
* 8, sizeof(keys
[i
]));
454 DES_set_odd_parity(keys
+ i
);
455 if(DES_is_weak_key(keys
+ i
))
456 xor(keys
+ i
, (const unsigned char*)"\0\0\0\0\0\0\0\xf0");
457 DES_set_key(keys
+ i
, &s
[i
]);
459 memset(&ivec
, 0, sizeof(ivec
));
460 DES_ede3_cbc_encrypt(tmp
,
462 &s
[0], &s
[1], &s
[2], &ivec
, DES_ENCRYPT
);
463 memset(s
, 0, sizeof(s
));
464 memset(&ivec
, 0, sizeof(ivec
));
465 for(i
= 0; i
< 3; i
++){
466 memcpy(keys
+ i
, tmp
+ i
* 8, sizeof(keys
[i
]));
467 DES_set_odd_parity(keys
+ i
);
468 if(DES_is_weak_key(keys
+ i
))
469 xor(keys
+ i
, (const unsigned char*)"\0\0\0\0\0\0\0\xf0");
471 memset(tmp
, 0, sizeof(tmp
));
473 key
->keytype
= enctype
;
474 krb5_data_copy(&key
->keyvalue
, keys
, sizeof(keys
));
475 memset(keys
, 0, sizeof(keys
));
481 static krb5_error_code
482 DES3_string_to_key_derived(krb5_context context
,
483 krb5_enctype enctype
,
490 size_t len
= password
.length
+ salt
.saltvalue
.length
;
494 if(len
!= 0 && s
== NULL
) {
495 krb5_set_error_string(context
, "malloc: out of memory");
498 memcpy(s
, password
.data
, password
.length
);
499 memcpy(s
+ password
.length
, salt
.saltvalue
.data
, salt
.saltvalue
.length
);
500 ret
= krb5_string_to_key_derived(context
,
511 DES3_random_to_key(krb5_context context
,
516 unsigned char *x
= key
->keyvalue
.data
;
517 const u_char
*q
= data
;
521 memset(x
, 0, sizeof(x
));
522 for (i
= 0; i
< 3; ++i
) {
524 for (j
= 0; j
< 7; ++j
) {
525 unsigned char b
= q
[7 * i
+ j
];
530 for (j
= 6; j
>= 0; --j
) {
531 foo
|= q
[7 * i
+ j
] & 1;
536 k
= key
->keyvalue
.data
;
537 for (i
= 0; i
< 3; i
++) {
538 DES_set_odd_parity(&k
[i
]);
539 if(DES_is_weak_key(&k
[i
]))
540 xor(&k
[i
], (const unsigned char*)"\0\0\0\0\0\0\0\xf0");
549 ARCFOUR_schedule(krb5_context context
,
552 RC4_set_key (kd
->schedule
->data
,
553 kd
->key
->keyvalue
.length
, kd
->key
->keyvalue
.data
);
556 static krb5_error_code
557 ARCFOUR_string_to_key(krb5_context context
,
558 krb5_enctype enctype
,
570 len
= 2 * password
.length
;
572 if (len
!= 0 && s
== NULL
) {
573 krb5_set_error_string(context
, "malloc: out of memory");
577 for (p
= s
, i
= 0; i
< password
.length
; ++i
) {
578 *p
++ = ((char *)password
.data
)[i
];
582 MD4_Update (&m
, s
, len
);
583 key
->keytype
= enctype
;
584 ret
= krb5_data_alloc (&key
->keyvalue
, 16);
586 krb5_set_error_string(context
, "malloc: out of memory");
589 MD4_Final (key
->keyvalue
.data
, &m
);
601 int _krb5_AES_string_to_default_iterator
= 4096;
603 static krb5_error_code
604 AES_string_to_key(krb5_context context
,
605 krb5_enctype enctype
,
613 struct encryption_type
*et
;
616 if (opaque
.length
== 0)
617 iter
= _krb5_AES_string_to_default_iterator
;
618 else if (opaque
.length
== 4) {
620 _krb5_get_int(opaque
.data
, &v
, 4);
621 iter
= ((uint32_t)v
);
623 return KRB5_PROG_KEYTYPE_NOSUPP
; /* XXX */
625 et
= _find_enctype(enctype
);
627 return KRB5_PROG_KEYTYPE_NOSUPP
;
632 krb5_set_error_string (context
, "malloc: out of memory");
635 kd
.key
->keytype
= enctype
;
636 ret
= krb5_data_alloc(&kd
.key
->keyvalue
, et
->keytype
->size
);
638 krb5_set_error_string(context
, "Failed to allocate pkcs5 key");
642 ret
= PKCS5_PBKDF2_HMAC_SHA1(password
.data
, password
.length
,
643 salt
.saltvalue
.data
, salt
.saltvalue
.length
,
645 et
->keytype
->size
, kd
.key
->keyvalue
.data
);
647 free_key_data(context
, &kd
);
648 krb5_set_error_string(context
, "Error calculating s2k");
649 return KRB5_PROG_KEYTYPE_NOSUPP
;
652 ret
= derive_key(context
, et
, &kd
, "kerberos", strlen("kerberos"));
654 ret
= krb5_copy_keyblock_contents(context
, kd
.key
, key
);
655 free_key_data(context
, &kd
);
660 struct krb5_aes_schedule
{
666 AES_schedule(krb5_context context
,
669 struct krb5_aes_schedule
*key
= kd
->schedule
->data
;
670 int bits
= kd
->key
->keyvalue
.length
* 8;
672 memset(key
, 0, sizeof(*key
));
673 AES_set_encrypt_key(kd
->key
->keyvalue
.data
, bits
, &key
->ekey
);
674 AES_set_decrypt_key(kd
->key
->keyvalue
.data
, bits
, &key
->dkey
);
681 static struct salt_type des_salt
[] = {
685 krb5_DES_string_to_key
687 #ifdef ENABLE_AFS_STRING_TO_KEY
691 DES_AFS3_string_to_key
697 static struct salt_type des3_salt
[] = {
706 static struct salt_type des3_salt_derived
[] = {
710 DES3_string_to_key_derived
715 static struct salt_type AES_salt
[] = {
724 static struct salt_type arcfour_salt
[] = {
728 ARCFOUR_string_to_key
737 static struct key_type keytype_null
= {
748 static struct key_type keytype_des
= {
753 sizeof(DES_key_schedule
),
757 krb5_DES_random_to_key
760 static struct key_type keytype_des3
= {
764 3 * sizeof(DES_cblock
),
765 3 * sizeof(DES_key_schedule
),
772 static struct key_type keytype_des3_derived
= {
776 3 * sizeof(DES_cblock
),
777 3 * sizeof(DES_key_schedule
),
784 static struct key_type keytype_aes128
= {
789 sizeof(struct krb5_aes_schedule
),
795 static struct key_type keytype_aes256
= {
800 sizeof(struct krb5_aes_schedule
),
806 static struct key_type keytype_arcfour
= {
817 static struct key_type
*keytypes
[] = {
820 &keytype_des3_derived
,
827 static int num_keytypes
= sizeof(keytypes
) / sizeof(keytypes
[0]);
829 static struct key_type
*
830 _find_keytype(krb5_keytype type
)
833 for(i
= 0; i
< num_keytypes
; i
++)
834 if(keytypes
[i
]->type
== type
)
840 /* coverity[+alloc : arg-*3] */
841 krb5_error_code KRB5_LIB_FUNCTION
842 krb5_salttype_to_string (krb5_context context
,
847 struct encryption_type
*e
;
848 struct salt_type
*st
;
850 e
= _find_enctype (etype
);
852 krb5_set_error_string(context
, "encryption type %d not supported",
854 return KRB5_PROG_ETYPE_NOSUPP
;
856 for (st
= e
->keytype
->string_to_key
; st
&& st
->type
; st
++) {
857 if (st
->type
== stype
) {
858 *string
= strdup (st
->name
);
859 if (*string
== NULL
) {
860 krb5_set_error_string(context
, "malloc: out of memory");
866 krb5_set_error_string(context
, "salttype %d not supported", stype
);
867 return HEIM_ERR_SALTTYPE_NOSUPP
;
870 krb5_error_code KRB5_LIB_FUNCTION
871 krb5_string_to_salttype (krb5_context context
,
874 krb5_salttype
*salttype
)
876 struct encryption_type
*e
;
877 struct salt_type
*st
;
879 e
= _find_enctype (etype
);
881 krb5_set_error_string(context
, "encryption type %d not supported",
883 return KRB5_PROG_ETYPE_NOSUPP
;
885 for (st
= e
->keytype
->string_to_key
; st
&& st
->type
; st
++) {
886 if (strcasecmp (st
->name
, string
) == 0) {
887 *salttype
= st
->type
;
891 krb5_set_error_string(context
, "salttype %s not supported", string
);
892 return HEIM_ERR_SALTTYPE_NOSUPP
;
895 krb5_error_code KRB5_LIB_FUNCTION
896 krb5_get_pw_salt(krb5_context context
,
897 krb5_const_principal principal
,
905 salt
->salttype
= KRB5_PW_SALT
;
906 len
= strlen(principal
->realm
);
907 for (i
= 0; i
< principal
->name
.name_string
.len
; ++i
)
908 len
+= strlen(principal
->name
.name_string
.val
[i
]);
909 ret
= krb5_data_alloc (&salt
->saltvalue
, len
);
912 p
= salt
->saltvalue
.data
;
913 memcpy (p
, principal
->realm
, strlen(principal
->realm
));
914 p
+= strlen(principal
->realm
);
915 for (i
= 0; i
< principal
->name
.name_string
.len
; ++i
) {
917 principal
->name
.name_string
.val
[i
],
918 strlen(principal
->name
.name_string
.val
[i
]));
919 p
+= strlen(principal
->name
.name_string
.val
[i
]);
924 krb5_error_code KRB5_LIB_FUNCTION
925 krb5_free_salt(krb5_context context
,
928 krb5_data_free(&salt
.saltvalue
);
932 krb5_error_code KRB5_LIB_FUNCTION
933 krb5_string_to_key_data (krb5_context context
,
934 krb5_enctype enctype
,
936 krb5_principal principal
,
942 ret
= krb5_get_pw_salt(context
, principal
, &salt
);
945 ret
= krb5_string_to_key_data_salt(context
, enctype
, password
, salt
, key
);
946 krb5_free_salt(context
, salt
);
950 krb5_error_code KRB5_LIB_FUNCTION
951 krb5_string_to_key (krb5_context context
,
952 krb5_enctype enctype
,
953 const char *password
,
954 krb5_principal principal
,
958 pw
.data
= rk_UNCONST(password
);
959 pw
.length
= strlen(password
);
960 return krb5_string_to_key_data(context
, enctype
, pw
, principal
, key
);
963 krb5_error_code KRB5_LIB_FUNCTION
964 krb5_string_to_key_data_salt (krb5_context context
,
965 krb5_enctype enctype
,
971 krb5_data_zero(&opaque
);
972 return krb5_string_to_key_data_salt_opaque(context
, enctype
, password
,
977 * Do a string -> key for encryption type `enctype' operation on
978 * `password' (with salt `salt' and the enctype specific data string
979 * `opaque'), returning the resulting key in `key'
982 krb5_error_code KRB5_LIB_FUNCTION
983 krb5_string_to_key_data_salt_opaque (krb5_context context
,
984 krb5_enctype enctype
,
990 struct encryption_type
*et
=_find_enctype(enctype
);
991 struct salt_type
*st
;
993 krb5_set_error_string(context
, "encryption type %d not supported",
995 return KRB5_PROG_ETYPE_NOSUPP
;
997 for(st
= et
->keytype
->string_to_key
; st
&& st
->type
; st
++)
998 if(st
->type
== salt
.salttype
)
999 return (*st
->string_to_key
)(context
, enctype
, password
,
1001 krb5_set_error_string(context
, "salt type %d not supported",
1003 return HEIM_ERR_SALTTYPE_NOSUPP
;
1007 * Do a string -> key for encryption type `enctype' operation on the
1008 * string `password' (with salt `salt'), returning the resulting key
1012 krb5_error_code KRB5_LIB_FUNCTION
1013 krb5_string_to_key_salt (krb5_context context
,
1014 krb5_enctype enctype
,
1015 const char *password
,
1020 pw
.data
= rk_UNCONST(password
);
1021 pw
.length
= strlen(password
);
1022 return krb5_string_to_key_data_salt(context
, enctype
, pw
, salt
, key
);
1025 krb5_error_code KRB5_LIB_FUNCTION
1026 krb5_string_to_key_salt_opaque (krb5_context context
,
1027 krb5_enctype enctype
,
1028 const char *password
,
1034 pw
.data
= rk_UNCONST(password
);
1035 pw
.length
= strlen(password
);
1036 return krb5_string_to_key_data_salt_opaque(context
, enctype
,
1037 pw
, salt
, opaque
, key
);
1040 krb5_error_code KRB5_LIB_FUNCTION
1041 krb5_keytype_to_string(krb5_context context
,
1042 krb5_keytype keytype
,
1045 struct key_type
*kt
= _find_keytype(keytype
);
1047 krb5_set_error_string(context
, "key type %d not supported", keytype
);
1048 return KRB5_PROG_KEYTYPE_NOSUPP
;
1050 *string
= strdup(kt
->name
);
1051 if(*string
== NULL
) {
1052 krb5_set_error_string(context
, "malloc: out of memory");
1058 krb5_error_code KRB5_LIB_FUNCTION
1059 krb5_string_to_keytype(krb5_context context
,
1061 krb5_keytype
*keytype
)
1064 for(i
= 0; i
< num_keytypes
; i
++)
1065 if(strcasecmp(keytypes
[i
]->name
, string
) == 0){
1066 *keytype
= keytypes
[i
]->type
;
1069 krb5_set_error_string(context
, "key type %s not supported", string
);
1070 return KRB5_PROG_KEYTYPE_NOSUPP
;
1073 krb5_error_code KRB5_LIB_FUNCTION
1074 krb5_enctype_keysize(krb5_context context
,
1078 struct encryption_type
*et
= _find_enctype(type
);
1080 krb5_set_error_string(context
, "encryption type %d not supported",
1082 return KRB5_PROG_ETYPE_NOSUPP
;
1084 *keysize
= et
->keytype
->size
;
1088 krb5_error_code KRB5_LIB_FUNCTION
1089 krb5_enctype_keybits(krb5_context context
,
1093 struct encryption_type
*et
= _find_enctype(type
);
1095 krb5_set_error_string(context
, "encryption type %d not supported",
1097 return KRB5_PROG_ETYPE_NOSUPP
;
1099 *keybits
= et
->keytype
->bits
;
1103 krb5_error_code KRB5_LIB_FUNCTION
1104 krb5_generate_random_keyblock(krb5_context context
,
1108 krb5_error_code ret
;
1109 struct encryption_type
*et
= _find_enctype(type
);
1111 krb5_set_error_string(context
, "encryption type %d not supported",
1113 return KRB5_PROG_ETYPE_NOSUPP
;
1115 ret
= krb5_data_alloc(&key
->keyvalue
, et
->keytype
->size
);
1118 key
->keytype
= type
;
1119 if(et
->keytype
->random_key
)
1120 (*et
->keytype
->random_key
)(context
, key
);
1122 krb5_generate_random_block(key
->keyvalue
.data
,
1123 key
->keyvalue
.length
);
1127 static krb5_error_code
1128 _key_schedule(krb5_context context
,
1129 struct key_data
*key
)
1131 krb5_error_code ret
;
1132 struct encryption_type
*et
= _find_enctype(key
->key
->keytype
);
1133 struct key_type
*kt
= et
->keytype
;
1135 if(kt
->schedule
== NULL
)
1137 if (key
->schedule
!= NULL
)
1139 ALLOC(key
->schedule
, 1);
1140 if(key
->schedule
== NULL
) {
1141 krb5_set_error_string(context
, "malloc: out of memory");
1144 ret
= krb5_data_alloc(key
->schedule
, kt
->schedule_size
);
1146 free(key
->schedule
);
1147 key
->schedule
= NULL
;
1150 (*kt
->schedule
)(context
, key
);
1154 /************************************************************
1156 ************************************************************/
1159 NONE_checksum(krb5_context context
,
1160 struct key_data
*key
,
1169 CRC32_checksum(krb5_context context
,
1170 struct key_data
*key
,
1177 unsigned char *r
= C
->checksum
.data
;
1178 _krb5_crc_init_table ();
1179 crc
= _krb5_crc_update (data
, len
, 0);
1181 r
[1] = (crc
>> 8) & 0xff;
1182 r
[2] = (crc
>> 16) & 0xff;
1183 r
[3] = (crc
>> 24) & 0xff;
1187 RSA_MD4_checksum(krb5_context context
,
1188 struct key_data
*key
,
1197 MD4_Update (&m
, data
, len
);
1198 MD4_Final (C
->checksum
.data
, &m
);
1202 RSA_MD4_DES_checksum(krb5_context context
,
1203 struct key_data
*key
,
1211 unsigned char *p
= cksum
->checksum
.data
;
1213 krb5_generate_random_block(p
, 8);
1215 MD4_Update (&md4
, p
, 8);
1216 MD4_Update (&md4
, data
, len
);
1217 MD4_Final (p
+ 8, &md4
);
1218 memset (&ivec
, 0, sizeof(ivec
));
1222 key
->schedule
->data
,
1227 static krb5_error_code
1228 RSA_MD4_DES_verify(krb5_context context
,
1229 struct key_data
*key
,
1236 unsigned char tmp
[24];
1237 unsigned char res
[16];
1239 krb5_error_code ret
= 0;
1241 memset(&ivec
, 0, sizeof(ivec
));
1242 DES_cbc_encrypt(C
->checksum
.data
,
1245 key
->schedule
->data
,
1249 MD4_Update (&md4
, tmp
, 8); /* confounder */
1250 MD4_Update (&md4
, data
, len
);
1251 MD4_Final (res
, &md4
);
1252 if(memcmp(res
, tmp
+ 8, sizeof(res
)) != 0) {
1253 krb5_clear_error_string (context
);
1254 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
1256 memset(tmp
, 0, sizeof(tmp
));
1257 memset(res
, 0, sizeof(res
));
1262 RSA_MD5_checksum(krb5_context context
,
1263 struct key_data
*key
,
1272 MD5_Update(&m
, data
, len
);
1273 MD5_Final (C
->checksum
.data
, &m
);
1277 RSA_MD5_DES_checksum(krb5_context context
,
1278 struct key_data
*key
,
1286 unsigned char *p
= C
->checksum
.data
;
1288 krb5_generate_random_block(p
, 8);
1290 MD5_Update (&md5
, p
, 8);
1291 MD5_Update (&md5
, data
, len
);
1292 MD5_Final (p
+ 8, &md5
);
1293 memset (&ivec
, 0, sizeof(ivec
));
1297 key
->schedule
->data
,
1302 static krb5_error_code
1303 RSA_MD5_DES_verify(krb5_context context
,
1304 struct key_data
*key
,
1311 unsigned char tmp
[24];
1312 unsigned char res
[16];
1314 DES_key_schedule
*sched
= key
->schedule
->data
;
1315 krb5_error_code ret
= 0;
1317 memset(&ivec
, 0, sizeof(ivec
));
1318 DES_cbc_encrypt(C
->checksum
.data
,
1325 MD5_Update (&md5
, tmp
, 8); /* confounder */
1326 MD5_Update (&md5
, data
, len
);
1327 MD5_Final (res
, &md5
);
1328 if(memcmp(res
, tmp
+ 8, sizeof(res
)) != 0) {
1329 krb5_clear_error_string (context
);
1330 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
1332 memset(tmp
, 0, sizeof(tmp
));
1333 memset(res
, 0, sizeof(res
));
1338 RSA_MD5_DES3_checksum(krb5_context context
,
1339 struct key_data
*key
,
1347 unsigned char *p
= C
->checksum
.data
;
1348 DES_key_schedule
*sched
= key
->schedule
->data
;
1350 krb5_generate_random_block(p
, 8);
1352 MD5_Update (&md5
, p
, 8);
1353 MD5_Update (&md5
, data
, len
);
1354 MD5_Final (p
+ 8, &md5
);
1355 memset (&ivec
, 0, sizeof(ivec
));
1356 DES_ede3_cbc_encrypt(p
,
1359 &sched
[0], &sched
[1], &sched
[2],
1364 static krb5_error_code
1365 RSA_MD5_DES3_verify(krb5_context context
,
1366 struct key_data
*key
,
1373 unsigned char tmp
[24];
1374 unsigned char res
[16];
1376 DES_key_schedule
*sched
= key
->schedule
->data
;
1377 krb5_error_code ret
= 0;
1379 memset(&ivec
, 0, sizeof(ivec
));
1380 DES_ede3_cbc_encrypt(C
->checksum
.data
,
1383 &sched
[0], &sched
[1], &sched
[2],
1387 MD5_Update (&md5
, tmp
, 8); /* confounder */
1388 MD5_Update (&md5
, data
, len
);
1389 MD5_Final (res
, &md5
);
1390 if(memcmp(res
, tmp
+ 8, sizeof(res
)) != 0) {
1391 krb5_clear_error_string (context
);
1392 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
1394 memset(tmp
, 0, sizeof(tmp
));
1395 memset(res
, 0, sizeof(res
));
1400 SHA1_checksum(krb5_context context
,
1401 struct key_data
*key
,
1410 SHA1_Update(&m
, data
, len
);
1411 SHA1_Final(C
->checksum
.data
, &m
);
1414 /* HMAC according to RFC2104 */
1415 static krb5_error_code
1416 hmac(krb5_context context
,
1417 struct checksum_type
*cm
,
1421 struct key_data
*keyblock
,
1424 unsigned char *ipad
, *opad
;
1429 ipad
= malloc(cm
->blocksize
+ len
);
1432 opad
= malloc(cm
->blocksize
+ cm
->checksumsize
);
1437 memset(ipad
, 0x36, cm
->blocksize
);
1438 memset(opad
, 0x5c, cm
->blocksize
);
1440 if(keyblock
->key
->keyvalue
.length
> cm
->blocksize
){
1441 (*cm
->checksum
)(context
,
1443 keyblock
->key
->keyvalue
.data
,
1444 keyblock
->key
->keyvalue
.length
,
1447 key
= result
->checksum
.data
;
1448 key_len
= result
->checksum
.length
;
1450 key
= keyblock
->key
->keyvalue
.data
;
1451 key_len
= keyblock
->key
->keyvalue
.length
;
1453 for(i
= 0; i
< key_len
; i
++){
1457 memcpy(ipad
+ cm
->blocksize
, data
, len
);
1458 (*cm
->checksum
)(context
, keyblock
, ipad
, cm
->blocksize
+ len
,
1460 memcpy(opad
+ cm
->blocksize
, result
->checksum
.data
,
1461 result
->checksum
.length
);
1462 (*cm
->checksum
)(context
, keyblock
, opad
,
1463 cm
->blocksize
+ cm
->checksumsize
, usage
, result
);
1464 memset(ipad
, 0, cm
->blocksize
+ len
);
1466 memset(opad
, 0, cm
->blocksize
+ cm
->checksumsize
);
1472 krb5_error_code KRB5_LIB_FUNCTION
1473 krb5_hmac(krb5_context context
,
1474 krb5_cksumtype cktype
,
1481 struct checksum_type
*c
= _find_checksum(cktype
);
1483 krb5_error_code ret
;
1486 krb5_set_error_string (context
, "checksum type %d not supported",
1488 return KRB5_PROG_SUMTYPE_NOSUPP
;
1494 ret
= hmac(context
, c
, data
, len
, usage
, &kd
, result
);
1497 krb5_free_data(context
, kd
.schedule
);
1503 SP_HMAC_SHA1_checksum(krb5_context context
,
1504 struct key_data
*key
,
1510 struct checksum_type
*c
= _find_checksum(CKSUMTYPE_SHA1
);
1513 krb5_error_code ret
;
1515 res
.checksum
.data
= sha1_data
;
1516 res
.checksum
.length
= sizeof(sha1_data
);
1518 ret
= hmac(context
, c
, data
, len
, usage
, key
, &res
);
1520 krb5_abortx(context
, "hmac failed");
1521 memcpy(result
->checksum
.data
, res
.checksum
.data
, result
->checksum
.length
);
1525 * checksum according to section 5. of draft-brezak-win2k-krb-rc4-hmac-03.txt
1529 HMAC_MD5_checksum(krb5_context context
,
1530 struct key_data
*key
,
1537 struct checksum_type
*c
= _find_checksum (CKSUMTYPE_RSA_MD5
);
1538 const char signature
[] = "signaturekey";
1540 struct key_data ksign
;
1543 unsigned char tmp
[16];
1544 unsigned char ksign_c_data
[16];
1545 krb5_error_code ret
;
1547 ksign_c
.checksum
.length
= sizeof(ksign_c_data
);
1548 ksign_c
.checksum
.data
= ksign_c_data
;
1549 ret
= hmac(context
, c
, signature
, sizeof(signature
), 0, key
, &ksign_c
);
1551 krb5_abortx(context
, "hmac failed");
1553 kb
.keyvalue
= ksign_c
.checksum
;
1555 t
[0] = (usage
>> 0) & 0xFF;
1556 t
[1] = (usage
>> 8) & 0xFF;
1557 t
[2] = (usage
>> 16) & 0xFF;
1558 t
[3] = (usage
>> 24) & 0xFF;
1559 MD5_Update (&md5
, t
, 4);
1560 MD5_Update (&md5
, data
, len
);
1561 MD5_Final (tmp
, &md5
);
1562 ret
= hmac(context
, c
, tmp
, sizeof(tmp
), 0, &ksign
, result
);
1564 krb5_abortx(context
, "hmac failed");
1568 * same as previous but being used while encrypting.
1572 HMAC_MD5_checksum_enc(krb5_context context
,
1573 struct key_data
*key
,
1579 struct checksum_type
*c
= _find_checksum (CKSUMTYPE_RSA_MD5
);
1581 struct key_data ksign
;
1584 unsigned char ksign_c_data
[16];
1585 krb5_error_code ret
;
1587 t
[0] = (usage
>> 0) & 0xFF;
1588 t
[1] = (usage
>> 8) & 0xFF;
1589 t
[2] = (usage
>> 16) & 0xFF;
1590 t
[3] = (usage
>> 24) & 0xFF;
1592 ksign_c
.checksum
.length
= sizeof(ksign_c_data
);
1593 ksign_c
.checksum
.data
= ksign_c_data
;
1594 ret
= hmac(context
, c
, t
, sizeof(t
), 0, key
, &ksign_c
);
1596 krb5_abortx(context
, "hmac failed");
1598 kb
.keyvalue
= ksign_c
.checksum
;
1599 ret
= hmac(context
, c
, data
, len
, 0, &ksign
, result
);
1601 krb5_abortx(context
, "hmac failed");
1604 static struct checksum_type checksum_none
= {
1613 static struct checksum_type checksum_crc32
= {
1622 static struct checksum_type checksum_rsa_md4
= {
1631 static struct checksum_type checksum_rsa_md4_des
= {
1632 CKSUMTYPE_RSA_MD4_DES
,
1636 F_KEYED
| F_CPROOF
| F_VARIANT
,
1637 RSA_MD4_DES_checksum
,
1641 static struct checksum_type checksum_des_mac
= {
1649 static struct checksum_type checksum_des_mac_k
= {
1650 CKSUMTYPE_DES_MAC_K
,
1657 static struct checksum_type checksum_rsa_md4_des_k
= {
1658 CKSUMTYPE_RSA_MD4_DES_K
,
1663 RSA_MD4_DES_K_checksum
,
1664 RSA_MD4_DES_K_verify
1667 static struct checksum_type checksum_rsa_md5
= {
1676 static struct checksum_type checksum_rsa_md5_des
= {
1677 CKSUMTYPE_RSA_MD5_DES
,
1681 F_KEYED
| F_CPROOF
| F_VARIANT
,
1682 RSA_MD5_DES_checksum
,
1685 static struct checksum_type checksum_rsa_md5_des3
= {
1686 CKSUMTYPE_RSA_MD5_DES3
,
1690 F_KEYED
| F_CPROOF
| F_VARIANT
,
1691 RSA_MD5_DES3_checksum
,
1694 static struct checksum_type checksum_sha1
= {
1703 static struct checksum_type checksum_hmac_sha1_des3
= {
1704 CKSUMTYPE_HMAC_SHA1_DES3
,
1708 F_KEYED
| F_CPROOF
| F_DERIVED
,
1709 SP_HMAC_SHA1_checksum
,
1713 static struct checksum_type checksum_hmac_sha1_aes128
= {
1714 CKSUMTYPE_HMAC_SHA1_96_AES_128
,
1715 "hmac-sha1-96-aes128",
1718 F_KEYED
| F_CPROOF
| F_DERIVED
,
1719 SP_HMAC_SHA1_checksum
,
1723 static struct checksum_type checksum_hmac_sha1_aes256
= {
1724 CKSUMTYPE_HMAC_SHA1_96_AES_256
,
1725 "hmac-sha1-96-aes256",
1728 F_KEYED
| F_CPROOF
| F_DERIVED
,
1729 SP_HMAC_SHA1_checksum
,
1733 static struct checksum_type checksum_hmac_md5
= {
1743 static struct checksum_type checksum_hmac_md5_enc
= {
1744 CKSUMTYPE_HMAC_MD5_ENC
,
1748 F_KEYED
| F_CPROOF
| F_PSEUDO
,
1749 HMAC_MD5_checksum_enc
,
1753 static struct checksum_type
*checksum_types
[] = {
1757 &checksum_rsa_md4_des
,
1760 &checksum_des_mac_k
,
1761 &checksum_rsa_md4_des_k
,
1764 &checksum_rsa_md5_des
,
1765 &checksum_rsa_md5_des3
,
1767 &checksum_hmac_sha1_des3
,
1768 &checksum_hmac_sha1_aes128
,
1769 &checksum_hmac_sha1_aes256
,
1771 &checksum_hmac_md5_enc
1774 static int num_checksums
= sizeof(checksum_types
) / sizeof(checksum_types
[0]);
1776 static struct checksum_type
*
1777 _find_checksum(krb5_cksumtype type
)
1780 for(i
= 0; i
< num_checksums
; i
++)
1781 if(checksum_types
[i
]->type
== type
)
1782 return checksum_types
[i
];
1786 static krb5_error_code
1787 get_checksum_key(krb5_context context
,
1789 unsigned usage
, /* not krb5_key_usage */
1790 struct checksum_type
*ct
,
1791 struct key_data
**key
)
1793 krb5_error_code ret
= 0;
1795 if(ct
->flags
& F_DERIVED
)
1796 ret
= _get_derived_key(context
, crypto
, usage
, key
);
1797 else if(ct
->flags
& F_VARIANT
) {
1800 *key
= _new_derived_key(crypto
, 0xff/* KRB5_KU_RFC1510_VARIANT */);
1802 krb5_set_error_string(context
, "malloc: out of memory");
1805 ret
= krb5_copy_keyblock(context
, crypto
->key
.key
, &(*key
)->key
);
1808 for(i
= 0; i
< (*key
)->key
->keyvalue
.length
; i
++)
1809 ((unsigned char*)(*key
)->key
->keyvalue
.data
)[i
] ^= 0xF0;
1811 *key
= &crypto
->key
;
1814 ret
= _key_schedule(context
, *key
);
1818 static krb5_error_code
1819 create_checksum (krb5_context context
,
1820 struct checksum_type
*ct
,
1827 krb5_error_code ret
;
1828 struct key_data
*dkey
;
1831 if (ct
->flags
& F_DISABLED
) {
1832 krb5_clear_error_string (context
);
1833 return KRB5_PROG_SUMTYPE_NOSUPP
;
1835 keyed_checksum
= (ct
->flags
& F_KEYED
) != 0;
1836 if(keyed_checksum
&& crypto
== NULL
) {
1837 krb5_set_error_string (context
, "Checksum type %s is keyed "
1838 "but no crypto context (key) was passed in",
1840 return KRB5_PROG_SUMTYPE_NOSUPP
; /* XXX */
1842 if(keyed_checksum
) {
1843 ret
= get_checksum_key(context
, crypto
, usage
, ct
, &dkey
);
1848 result
->cksumtype
= ct
->type
;
1849 ret
= krb5_data_alloc(&result
->checksum
, ct
->checksumsize
);
1852 (*ct
->checksum
)(context
, dkey
, data
, len
, usage
, result
);
1857 arcfour_checksum_p(struct checksum_type
*ct
, krb5_crypto crypto
)
1859 return (ct
->type
== CKSUMTYPE_HMAC_MD5
) &&
1860 (crypto
->key
.key
->keytype
== KEYTYPE_ARCFOUR
);
1863 krb5_error_code KRB5_LIB_FUNCTION
1864 krb5_create_checksum(krb5_context context
,
1866 krb5_key_usage usage
,
1872 struct checksum_type
*ct
= NULL
;
1875 /* type 0 -> pick from crypto */
1877 ct
= _find_checksum(type
);
1878 } else if (crypto
) {
1879 ct
= crypto
->et
->keyed_checksum
;
1881 ct
= crypto
->et
->checksum
;
1885 krb5_set_error_string (context
, "checksum type %d not supported",
1887 return KRB5_PROG_SUMTYPE_NOSUPP
;
1890 if (arcfour_checksum_p(ct
, crypto
)) {
1892 usage2arcfour(context
, &keyusage
);
1894 keyusage
= CHECKSUM_USAGE(usage
);
1896 return create_checksum(context
, ct
, crypto
, keyusage
,
1900 static krb5_error_code
1901 verify_checksum(krb5_context context
,
1903 unsigned usage
, /* not krb5_key_usage */
1908 krb5_error_code ret
;
1909 struct key_data
*dkey
;
1912 struct checksum_type
*ct
;
1914 ct
= _find_checksum(cksum
->cksumtype
);
1915 if (ct
== NULL
|| (ct
->flags
& F_DISABLED
)) {
1916 krb5_set_error_string (context
, "checksum type %d not supported",
1918 return KRB5_PROG_SUMTYPE_NOSUPP
;
1920 if(ct
->checksumsize
!= cksum
->checksum
.length
) {
1921 krb5_clear_error_string (context
);
1922 return KRB5KRB_AP_ERR_BAD_INTEGRITY
; /* XXX */
1924 keyed_checksum
= (ct
->flags
& F_KEYED
) != 0;
1925 if(keyed_checksum
&& crypto
== NULL
) {
1926 krb5_set_error_string (context
, "Checksum type %s is keyed "
1927 "but no crypto context (key) was passed in",
1929 return KRB5_PROG_SUMTYPE_NOSUPP
; /* XXX */
1932 ret
= get_checksum_key(context
, crypto
, usage
, ct
, &dkey
);
1936 return (*ct
->verify
)(context
, dkey
, data
, len
, usage
, cksum
);
1938 ret
= krb5_data_alloc (&c
.checksum
, ct
->checksumsize
);
1942 (*ct
->checksum
)(context
, dkey
, data
, len
, usage
, &c
);
1944 if(c
.checksum
.length
!= cksum
->checksum
.length
||
1945 memcmp(c
.checksum
.data
, cksum
->checksum
.data
, c
.checksum
.length
)) {
1946 krb5_clear_error_string (context
);
1947 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
1951 krb5_data_free (&c
.checksum
);
1955 krb5_error_code KRB5_LIB_FUNCTION
1956 krb5_verify_checksum(krb5_context context
,
1958 krb5_key_usage usage
,
1963 struct checksum_type
*ct
;
1966 ct
= _find_checksum(cksum
->cksumtype
);
1968 krb5_set_error_string (context
, "checksum type %d not supported",
1970 return KRB5_PROG_SUMTYPE_NOSUPP
;
1973 if (arcfour_checksum_p(ct
, crypto
)) {
1975 usage2arcfour(context
, &keyusage
);
1977 keyusage
= CHECKSUM_USAGE(usage
);
1979 return verify_checksum(context
, crypto
, keyusage
,
1983 krb5_error_code KRB5_LIB_FUNCTION
1984 krb5_crypto_get_checksum_type(krb5_context context
,
1986 krb5_cksumtype
*type
)
1988 struct checksum_type
*ct
= NULL
;
1990 if (crypto
!= NULL
) {
1991 ct
= crypto
->et
->keyed_checksum
;
1993 ct
= crypto
->et
->checksum
;
1997 krb5_set_error_string (context
, "checksum type not found");
1998 return KRB5_PROG_SUMTYPE_NOSUPP
;
2007 krb5_error_code KRB5_LIB_FUNCTION
2008 krb5_checksumsize(krb5_context context
,
2009 krb5_cksumtype type
,
2012 struct checksum_type
*ct
= _find_checksum(type
);
2014 krb5_set_error_string (context
, "checksum type %d not supported",
2016 return KRB5_PROG_SUMTYPE_NOSUPP
;
2018 *size
= ct
->checksumsize
;
2022 krb5_boolean KRB5_LIB_FUNCTION
2023 krb5_checksum_is_keyed(krb5_context context
,
2024 krb5_cksumtype type
)
2026 struct checksum_type
*ct
= _find_checksum(type
);
2029 krb5_set_error_string (context
, "checksum type %d not supported",
2031 return KRB5_PROG_SUMTYPE_NOSUPP
;
2033 return ct
->flags
& F_KEYED
;
2036 krb5_boolean KRB5_LIB_FUNCTION
2037 krb5_checksum_is_collision_proof(krb5_context context
,
2038 krb5_cksumtype type
)
2040 struct checksum_type
*ct
= _find_checksum(type
);
2043 krb5_set_error_string (context
, "checksum type %d not supported",
2045 return KRB5_PROG_SUMTYPE_NOSUPP
;
2047 return ct
->flags
& F_CPROOF
;
2050 krb5_error_code KRB5_LIB_FUNCTION
2051 krb5_checksum_disable(krb5_context context
,
2052 krb5_cksumtype type
)
2054 struct checksum_type
*ct
= _find_checksum(type
);
2057 krb5_set_error_string (context
, "checksum type %d not supported",
2059 return KRB5_PROG_SUMTYPE_NOSUPP
;
2061 ct
->flags
|= F_DISABLED
;
2065 /************************************************************
2067 ************************************************************/
2069 static krb5_error_code
2070 NULL_encrypt(krb5_context context
,
2071 struct key_data
*key
,
2074 krb5_boolean encryptp
,
2081 static krb5_error_code
2082 DES_CBC_encrypt_null_ivec(krb5_context context
,
2083 struct key_data
*key
,
2086 krb5_boolean encryptp
,
2091 DES_key_schedule
*s
= key
->schedule
->data
;
2092 memset(&ivec
, 0, sizeof(ivec
));
2093 DES_cbc_encrypt(data
, data
, len
, s
, &ivec
, encryptp
);
2097 static krb5_error_code
2098 DES_CBC_encrypt_key_ivec(krb5_context context
,
2099 struct key_data
*key
,
2102 krb5_boolean encryptp
,
2107 DES_key_schedule
*s
= key
->schedule
->data
;
2108 memcpy(&ivec
, key
->key
->keyvalue
.data
, sizeof(ivec
));
2109 DES_cbc_encrypt(data
, data
, len
, s
, &ivec
, encryptp
);
2113 static krb5_error_code
2114 DES3_CBC_encrypt(krb5_context context
,
2115 struct key_data
*key
,
2118 krb5_boolean encryptp
,
2122 DES_cblock local_ivec
;
2123 DES_key_schedule
*s
= key
->schedule
->data
;
2126 memset(local_ivec
, 0, sizeof(local_ivec
));
2128 DES_ede3_cbc_encrypt(data
, data
, len
, &s
[0], &s
[1], &s
[2], ivec
, encryptp
);
2132 static krb5_error_code
2133 DES_CFB64_encrypt_null_ivec(krb5_context context
,
2134 struct key_data
*key
,
2137 krb5_boolean encryptp
,
2143 DES_key_schedule
*s
= key
->schedule
->data
;
2144 memset(&ivec
, 0, sizeof(ivec
));
2146 DES_cfb64_encrypt(data
, data
, len
, s
, &ivec
, &num
, encryptp
);
2150 static krb5_error_code
2151 DES_PCBC_encrypt_key_ivec(krb5_context context
,
2152 struct key_data
*key
,
2155 krb5_boolean encryptp
,
2160 DES_key_schedule
*s
= key
->schedule
->data
;
2161 memcpy(&ivec
, key
->key
->keyvalue
.data
, sizeof(ivec
));
2163 DES_pcbc_encrypt(data
, data
, len
, s
, &ivec
, encryptp
);
2168 * AES draft-raeburn-krb-rijndael-krb-02
2171 void KRB5_LIB_FUNCTION
2172 _krb5_aes_cts_encrypt(const unsigned char *in
, unsigned char *out
,
2173 size_t len
, const AES_KEY
*key
,
2174 unsigned char *ivec
, const int encryptp
)
2176 unsigned char tmp
[AES_BLOCK_SIZE
];
2180 * In the framework of kerberos, the length can never be shorter
2181 * then at least one blocksize.
2186 while(len
> AES_BLOCK_SIZE
) {
2187 for (i
= 0; i
< AES_BLOCK_SIZE
; i
++)
2188 tmp
[i
] = in
[i
] ^ ivec
[i
];
2189 AES_encrypt(tmp
, out
, key
);
2190 memcpy(ivec
, out
, AES_BLOCK_SIZE
);
2191 len
-= AES_BLOCK_SIZE
;
2192 in
+= AES_BLOCK_SIZE
;
2193 out
+= AES_BLOCK_SIZE
;
2196 for (i
= 0; i
< len
; i
++)
2197 tmp
[i
] = in
[i
] ^ ivec
[i
];
2198 for (; i
< AES_BLOCK_SIZE
; i
++)
2199 tmp
[i
] = 0 ^ ivec
[i
];
2201 AES_encrypt(tmp
, out
- AES_BLOCK_SIZE
, key
);
2203 memcpy(out
, ivec
, len
);
2204 memcpy(ivec
, out
- AES_BLOCK_SIZE
, AES_BLOCK_SIZE
);
2207 unsigned char tmp2
[AES_BLOCK_SIZE
];
2208 unsigned char tmp3
[AES_BLOCK_SIZE
];
2210 while(len
> AES_BLOCK_SIZE
* 2) {
2211 memcpy(tmp
, in
, AES_BLOCK_SIZE
);
2212 AES_decrypt(in
, out
, key
);
2213 for (i
= 0; i
< AES_BLOCK_SIZE
; i
++)
2215 memcpy(ivec
, tmp
, AES_BLOCK_SIZE
);
2216 len
-= AES_BLOCK_SIZE
;
2217 in
+= AES_BLOCK_SIZE
;
2218 out
+= AES_BLOCK_SIZE
;
2221 len
-= AES_BLOCK_SIZE
;
2223 memcpy(tmp
, in
, AES_BLOCK_SIZE
); /* save last iv */
2224 AES_decrypt(in
, tmp2
, key
);
2226 memcpy(tmp3
, in
+ AES_BLOCK_SIZE
, len
);
2227 memcpy(tmp3
+ len
, tmp2
+ len
, AES_BLOCK_SIZE
- len
); /* xor 0 */
2229 for (i
= 0; i
< len
; i
++)
2230 out
[i
+ AES_BLOCK_SIZE
] = tmp2
[i
] ^ tmp3
[i
];
2232 AES_decrypt(tmp3
, out
, key
);
2233 for (i
= 0; i
< AES_BLOCK_SIZE
; i
++)
2235 memcpy(ivec
, tmp
, AES_BLOCK_SIZE
);
2239 static krb5_error_code
2240 AES_CTS_encrypt(krb5_context context
,
2241 struct key_data
*key
,
2244 krb5_boolean encryptp
,
2248 struct krb5_aes_schedule
*aeskey
= key
->schedule
->data
;
2249 char local_ivec
[AES_BLOCK_SIZE
];
2257 if (len
< AES_BLOCK_SIZE
)
2258 krb5_abortx(context
, "invalid use of AES_CTS_encrypt");
2259 if (len
== AES_BLOCK_SIZE
) {
2261 AES_encrypt(data
, data
, k
);
2263 AES_decrypt(data
, data
, k
);
2266 memset(local_ivec
, 0, sizeof(local_ivec
));
2269 _krb5_aes_cts_encrypt(data
, data
, len
, k
, ivec
, encryptp
);
2276 * section 6 of draft-brezak-win2k-krb-rc4-hmac-03
2278 * warning: not for small children
2281 static krb5_error_code
2282 ARCFOUR_subencrypt(krb5_context context
,
2283 struct key_data
*key
,
2289 struct checksum_type
*c
= _find_checksum (CKSUMTYPE_RSA_MD5
);
2290 Checksum k1_c
, k2_c
, k3_c
, cksum
;
2295 unsigned char *cdata
= data
;
2296 unsigned char k1_c_data
[16], k2_c_data
[16], k3_c_data
[16];
2297 krb5_error_code ret
;
2299 t
[0] = (usage
>> 0) & 0xFF;
2300 t
[1] = (usage
>> 8) & 0xFF;
2301 t
[2] = (usage
>> 16) & 0xFF;
2302 t
[3] = (usage
>> 24) & 0xFF;
2304 k1_c
.checksum
.length
= sizeof(k1_c_data
);
2305 k1_c
.checksum
.data
= k1_c_data
;
2307 ret
= hmac(NULL
, c
, t
, sizeof(t
), 0, key
, &k1_c
);
2309 krb5_abortx(context
, "hmac failed");
2311 memcpy (k2_c_data
, k1_c_data
, sizeof(k1_c_data
));
2313 k2_c
.checksum
.length
= sizeof(k2_c_data
);
2314 k2_c
.checksum
.data
= k2_c_data
;
2317 kb
.keyvalue
= k2_c
.checksum
;
2319 cksum
.checksum
.length
= 16;
2320 cksum
.checksum
.data
= data
;
2322 ret
= hmac(NULL
, c
, cdata
+ 16, len
- 16, 0, &ke
, &cksum
);
2324 krb5_abortx(context
, "hmac failed");
2327 kb
.keyvalue
= k1_c
.checksum
;
2329 k3_c
.checksum
.length
= sizeof(k3_c_data
);
2330 k3_c
.checksum
.data
= k3_c_data
;
2332 ret
= hmac(NULL
, c
, data
, 16, 0, &ke
, &k3_c
);
2334 krb5_abortx(context
, "hmac failed");
2336 RC4_set_key (&rc4_key
, k3_c
.checksum
.length
, k3_c
.checksum
.data
);
2337 RC4 (&rc4_key
, len
- 16, cdata
+ 16, cdata
+ 16);
2338 memset (k1_c_data
, 0, sizeof(k1_c_data
));
2339 memset (k2_c_data
, 0, sizeof(k2_c_data
));
2340 memset (k3_c_data
, 0, sizeof(k3_c_data
));
2344 static krb5_error_code
2345 ARCFOUR_subdecrypt(krb5_context context
,
2346 struct key_data
*key
,
2352 struct checksum_type
*c
= _find_checksum (CKSUMTYPE_RSA_MD5
);
2353 Checksum k1_c
, k2_c
, k3_c
, cksum
;
2358 unsigned char *cdata
= data
;
2359 unsigned char k1_c_data
[16], k2_c_data
[16], k3_c_data
[16];
2360 unsigned char cksum_data
[16];
2361 krb5_error_code ret
;
2363 t
[0] = (usage
>> 0) & 0xFF;
2364 t
[1] = (usage
>> 8) & 0xFF;
2365 t
[2] = (usage
>> 16) & 0xFF;
2366 t
[3] = (usage
>> 24) & 0xFF;
2368 k1_c
.checksum
.length
= sizeof(k1_c_data
);
2369 k1_c
.checksum
.data
= k1_c_data
;
2371 ret
= hmac(NULL
, c
, t
, sizeof(t
), 0, key
, &k1_c
);
2373 krb5_abortx(context
, "hmac failed");
2375 memcpy (k2_c_data
, k1_c_data
, sizeof(k1_c_data
));
2377 k2_c
.checksum
.length
= sizeof(k2_c_data
);
2378 k2_c
.checksum
.data
= k2_c_data
;
2381 kb
.keyvalue
= k1_c
.checksum
;
2383 k3_c
.checksum
.length
= sizeof(k3_c_data
);
2384 k3_c
.checksum
.data
= k3_c_data
;
2386 ret
= hmac(NULL
, c
, cdata
, 16, 0, &ke
, &k3_c
);
2388 krb5_abortx(context
, "hmac failed");
2390 RC4_set_key (&rc4_key
, k3_c
.checksum
.length
, k3_c
.checksum
.data
);
2391 RC4 (&rc4_key
, len
- 16, cdata
+ 16, cdata
+ 16);
2394 kb
.keyvalue
= k2_c
.checksum
;
2396 cksum
.checksum
.length
= 16;
2397 cksum
.checksum
.data
= cksum_data
;
2399 ret
= hmac(NULL
, c
, cdata
+ 16, len
- 16, 0, &ke
, &cksum
);
2401 krb5_abortx(context
, "hmac failed");
2403 memset (k1_c_data
, 0, sizeof(k1_c_data
));
2404 memset (k2_c_data
, 0, sizeof(k2_c_data
));
2405 memset (k3_c_data
, 0, sizeof(k3_c_data
));
2407 if (memcmp (cksum
.checksum
.data
, data
, 16) != 0) {
2408 krb5_clear_error_string (context
);
2409 return KRB5KRB_AP_ERR_BAD_INTEGRITY
;
2416 * convert the usage numbers used in
2417 * draft-ietf-cat-kerb-key-derivation-00.txt to the ones in
2418 * draft-brezak-win2k-krb-rc4-hmac-04.txt
2421 static krb5_error_code
2422 usage2arcfour (krb5_context context
, unsigned *usage
)
2425 case KRB5_KU_AS_REP_ENC_PART
: /* 3 */
2426 case KRB5_KU_TGS_REP_ENC_PART_SUB_KEY
: /* 9 */
2429 case KRB5_KU_USAGE_SEAL
: /* 22 */
2432 case KRB5_KU_USAGE_SIGN
: /* 23 */
2435 case KRB5_KU_USAGE_SEQ
: /* 24 */
2443 static krb5_error_code
2444 ARCFOUR_encrypt(krb5_context context
,
2445 struct key_data
*key
,
2448 krb5_boolean encryptp
,
2452 krb5_error_code ret
;
2453 unsigned keyusage
= usage
;
2455 if((ret
= usage2arcfour (context
, &keyusage
)) != 0)
2459 return ARCFOUR_subencrypt (context
, key
, data
, len
, keyusage
, ivec
);
2461 return ARCFOUR_subdecrypt (context
, key
, data
, len
, keyusage
, ivec
);
2469 static krb5_error_code
2470 AES_PRF(krb5_context context
,
2472 const krb5_data
*in
,
2475 struct checksum_type
*ct
= crypto
->et
->checksum
;
2476 krb5_error_code ret
;
2478 krb5_keyblock
*derived
;
2480 result
.cksumtype
= ct
->type
;
2481 ret
= krb5_data_alloc(&result
.checksum
, ct
->checksumsize
);
2483 krb5_set_error_string(context
, "out memory");
2487 (*ct
->checksum
)(context
, NULL
, in
->data
, in
->length
, 0, &result
);
2489 if (result
.checksum
.length
< crypto
->et
->blocksize
)
2490 krb5_abortx(context
, "internal prf error");
2493 ret
= krb5_derive_key(context
, crypto
->key
.key
,
2494 crypto
->et
->type
, "prf", 3, &derived
);
2496 krb5_abortx(context
, "krb5_derive_key");
2498 ret
= krb5_data_alloc(out
, crypto
->et
->blocksize
);
2500 krb5_abortx(context
, "malloc failed");
2505 AES_set_encrypt_key(derived
->keyvalue
.data
,
2506 crypto
->et
->keytype
->bits
, &key
);
2507 AES_encrypt(result
.checksum
.data
, out
->data
, &key
);
2508 memset(&key
, 0, sizeof(key
));
2511 krb5_data_free(&result
.checksum
);
2512 krb5_free_keyblock(context
, derived
);
2518 * these should currently be in reverse preference order.
2519 * (only relevant for !F_PSEUDO) */
2521 static struct encryption_type enctype_null
= {
2536 static struct encryption_type enctype_des_cbc_crc
= {
2547 DES_CBC_encrypt_key_ivec
,
2551 static struct encryption_type enctype_des_cbc_md4
= {
2560 &checksum_rsa_md4_des
,
2562 DES_CBC_encrypt_null_ivec
,
2566 static struct encryption_type enctype_des_cbc_md5
= {
2575 &checksum_rsa_md5_des
,
2577 DES_CBC_encrypt_null_ivec
,
2581 static struct encryption_type enctype_arcfour_hmac_md5
= {
2582 ETYPE_ARCFOUR_HMAC_MD5
,
2596 static struct encryption_type enctype_des3_cbc_md5
= {
2605 &checksum_rsa_md5_des3
,
2611 static struct encryption_type enctype_des3_cbc_sha1
= {
2612 ETYPE_DES3_CBC_SHA1
,
2618 &keytype_des3_derived
,
2620 &checksum_hmac_sha1_des3
,
2626 static struct encryption_type enctype_old_des3_cbc_sha1
= {
2627 ETYPE_OLD_DES3_CBC_SHA1
,
2628 "old-des3-cbc-sha1",
2635 &checksum_hmac_sha1_des3
,
2641 static struct encryption_type enctype_aes128_cts_hmac_sha1
= {
2642 ETYPE_AES128_CTS_HMAC_SHA1_96
,
2643 "aes128-cts-hmac-sha1-96",
2650 &checksum_hmac_sha1_aes128
,
2656 static struct encryption_type enctype_aes256_cts_hmac_sha1
= {
2657 ETYPE_AES256_CTS_HMAC_SHA1_96
,
2658 "aes256-cts-hmac-sha1-96",
2665 &checksum_hmac_sha1_aes256
,
2671 static struct encryption_type enctype_des_cbc_none
= {
2682 DES_CBC_encrypt_null_ivec
,
2686 static struct encryption_type enctype_des_cfb64_none
= {
2687 ETYPE_DES_CFB64_NONE
,
2697 DES_CFB64_encrypt_null_ivec
,
2701 static struct encryption_type enctype_des_pcbc_none
= {
2702 ETYPE_DES_PCBC_NONE
,
2712 DES_PCBC_encrypt_key_ivec
,
2716 static struct encryption_type enctype_des3_cbc_none
= {
2717 ETYPE_DES3_CBC_NONE
,
2723 &keytype_des3_derived
,
2732 static struct encryption_type
*etypes
[] = {
2734 &enctype_des_cbc_crc
,
2735 &enctype_des_cbc_md4
,
2736 &enctype_des_cbc_md5
,
2737 &enctype_arcfour_hmac_md5
,
2738 &enctype_des3_cbc_md5
,
2739 &enctype_des3_cbc_sha1
,
2740 &enctype_old_des3_cbc_sha1
,
2741 &enctype_aes128_cts_hmac_sha1
,
2742 &enctype_aes256_cts_hmac_sha1
,
2743 &enctype_des_cbc_none
,
2744 &enctype_des_cfb64_none
,
2745 &enctype_des_pcbc_none
,
2746 &enctype_des3_cbc_none
2749 static unsigned num_etypes
= sizeof(etypes
) / sizeof(etypes
[0]);
2752 static struct encryption_type
*
2753 _find_enctype(krb5_enctype type
)
2756 for(i
= 0; i
< num_etypes
; i
++)
2757 if(etypes
[i
]->type
== type
)
2763 krb5_error_code KRB5_LIB_FUNCTION
2764 krb5_enctype_to_string(krb5_context context
,
2768 struct encryption_type
*e
;
2769 e
= _find_enctype(etype
);
2771 krb5_set_error_string (context
, "encryption type %d not supported",
2774 return KRB5_PROG_ETYPE_NOSUPP
;
2776 *string
= strdup(e
->name
);
2777 if(*string
== NULL
) {
2778 krb5_set_error_string(context
, "malloc: out of memory");
2784 krb5_error_code KRB5_LIB_FUNCTION
2785 krb5_string_to_enctype(krb5_context context
,
2787 krb5_enctype
*etype
)
2790 for(i
= 0; i
< num_etypes
; i
++)
2791 if(strcasecmp(etypes
[i
]->name
, string
) == 0){
2792 *etype
= etypes
[i
]->type
;
2795 krb5_set_error_string (context
, "encryption type %s not supported",
2797 return KRB5_PROG_ETYPE_NOSUPP
;
2800 krb5_error_code KRB5_LIB_FUNCTION
2801 _krb5_enctype_to_oid(krb5_context context
,
2805 struct encryption_type
*et
= _find_enctype(etype
);
2807 krb5_set_error_string (context
, "encryption type %d not supported",
2809 return KRB5_PROG_ETYPE_NOSUPP
;
2811 if(et
->oid
== NULL
) {
2812 krb5_set_error_string (context
, "%s have not oid", et
->name
);
2813 return KRB5_PROG_ETYPE_NOSUPP
;
2815 krb5_clear_error_string(context
);
2816 return der_copy_oid(et
->oid
, oid
);
2819 krb5_error_code KRB5_LIB_FUNCTION
2820 _krb5_oid_to_enctype(krb5_context context
,
2821 const heim_oid
*oid
,
2822 krb5_enctype
*etype
)
2825 for(i
= 0; i
< num_etypes
; i
++) {
2826 if(etypes
[i
]->oid
&& der_heim_oid_cmp(etypes
[i
]->oid
, oid
) == 0) {
2827 *etype
= etypes
[i
]->type
;
2831 krb5_set_error_string(context
, "enctype for oid not supported");
2832 return KRB5_PROG_ETYPE_NOSUPP
;
2835 krb5_error_code KRB5_LIB_FUNCTION
2836 krb5_enctype_to_keytype(krb5_context context
,
2838 krb5_keytype
*keytype
)
2840 struct encryption_type
*e
= _find_enctype(etype
);
2842 krb5_set_error_string (context
, "encryption type %d not supported",
2844 return KRB5_PROG_ETYPE_NOSUPP
;
2846 *keytype
= e
->keytype
->type
; /* XXX */
2851 krb5_error_code KRB5_LIB_FUNCTION
2852 krb5_keytype_to_enctype(krb5_context context
,
2853 krb5_keytype keytype
,
2854 krb5_enctype
*etype
)
2856 struct key_type
*kt
= _find_keytype(keytype
);
2857 krb5_warnx(context
, "krb5_keytype_to_enctype(%u)", keytype
);
2859 return KRB5_PROG_KEYTYPE_NOSUPP
;
2860 *etype
= kt
->best_etype
;
2865 krb5_error_code KRB5_LIB_FUNCTION
2866 krb5_keytype_to_enctypes (krb5_context context
,
2867 krb5_keytype keytype
,
2875 for (i
= num_etypes
- 1; i
>= 0; --i
) {
2876 if (etypes
[i
]->keytype
->type
== keytype
2877 && !(etypes
[i
]->flags
& F_PSEUDO
))
2880 ret
= malloc(n
* sizeof(*ret
));
2881 if (ret
== NULL
&& n
!= 0) {
2882 krb5_set_error_string(context
, "malloc: out of memory");
2886 for (i
= num_etypes
- 1; i
>= 0; --i
) {
2887 if (etypes
[i
]->keytype
->type
== keytype
2888 && !(etypes
[i
]->flags
& F_PSEUDO
))
2889 ret
[n
++] = etypes
[i
]->type
;
2897 * First take the configured list of etypes for `keytype' if available,
2898 * else, do `krb5_keytype_to_enctypes'.
2901 krb5_error_code KRB5_LIB_FUNCTION
2902 krb5_keytype_to_enctypes_default (krb5_context context
,
2903 krb5_keytype keytype
,
2910 if (keytype
!= KEYTYPE_DES
|| context
->etypes_des
== NULL
)
2911 return krb5_keytype_to_enctypes (context
, keytype
, len
, val
);
2913 for (n
= 0; context
->etypes_des
[n
]; ++n
)
2915 ret
= malloc (n
* sizeof(*ret
));
2916 if (ret
== NULL
&& n
!= 0) {
2917 krb5_set_error_string(context
, "malloc: out of memory");
2920 for (i
= 0; i
< n
; ++i
)
2921 ret
[i
] = context
->etypes_des
[i
];
2927 krb5_error_code KRB5_LIB_FUNCTION
2928 krb5_enctype_valid(krb5_context context
,
2931 struct encryption_type
*e
= _find_enctype(etype
);
2933 krb5_set_error_string (context
, "encryption type %d not supported",
2935 return KRB5_PROG_ETYPE_NOSUPP
;
2937 if (e
->flags
& F_DISABLED
) {
2938 krb5_set_error_string (context
, "encryption type %s is disabled",
2940 return KRB5_PROG_ETYPE_NOSUPP
;
2945 krb5_error_code KRB5_LIB_FUNCTION
2946 krb5_cksumtype_valid(krb5_context context
,
2947 krb5_cksumtype ctype
)
2949 struct checksum_type
*c
= _find_checksum(ctype
);
2951 krb5_set_error_string (context
, "checksum type %d not supported",
2953 return KRB5_PROG_SUMTYPE_NOSUPP
;
2955 if (c
->flags
& F_DISABLED
) {
2956 krb5_set_error_string (context
, "checksum type %s is disabled",
2958 return KRB5_PROG_SUMTYPE_NOSUPP
;
2964 /* if two enctypes have compatible keys */
2965 krb5_boolean KRB5_LIB_FUNCTION
2966 krb5_enctypes_compatible_keys(krb5_context context
,
2967 krb5_enctype etype1
,
2968 krb5_enctype etype2
)
2970 struct encryption_type
*e1
= _find_enctype(etype1
);
2971 struct encryption_type
*e2
= _find_enctype(etype2
);
2972 return e1
!= NULL
&& e2
!= NULL
&& e1
->keytype
== e2
->keytype
;
2976 derived_crypto(krb5_context context
,
2979 return (crypto
->et
->flags
& F_DERIVED
) != 0;
2983 special_crypto(krb5_context context
,
2986 return (crypto
->et
->flags
& F_SPECIAL
) != 0;
2989 #define CHECKSUMSIZE(C) ((C)->checksumsize)
2990 #define CHECKSUMTYPE(C) ((C)->type)
2992 static krb5_error_code
2993 encrypt_internal_derived(krb5_context context
,
3001 size_t sz
, block_sz
, checksum_sz
, total_sz
;
3003 unsigned char *p
, *q
;
3004 krb5_error_code ret
;
3005 struct key_data
*dkey
;
3006 const struct encryption_type
*et
= crypto
->et
;
3008 checksum_sz
= CHECKSUMSIZE(et
->keyed_checksum
);
3010 sz
= et
->confoundersize
+ len
;
3011 block_sz
= (sz
+ et
->padsize
- 1) &~ (et
->padsize
- 1); /* pad */
3012 total_sz
= block_sz
+ checksum_sz
;
3013 p
= calloc(1, total_sz
);
3015 krb5_set_error_string(context
, "malloc: out of memory");
3020 krb5_generate_random_block(q
, et
->confoundersize
); /* XXX */
3021 q
+= et
->confoundersize
;
3022 memcpy(q
, data
, len
);
3024 ret
= create_checksum(context
,
3027 INTEGRITY_USAGE(usage
),
3031 if(ret
== 0 && cksum
.checksum
.length
!= checksum_sz
) {
3032 free_Checksum (&cksum
);
3033 krb5_clear_error_string (context
);
3034 ret
= KRB5_CRYPTO_INTERNAL
;
3038 memcpy(p
+ block_sz
, cksum
.checksum
.data
, cksum
.checksum
.length
);
3039 free_Checksum (&cksum
);
3040 ret
= _get_derived_key(context
, crypto
, ENCRYPTION_USAGE(usage
), &dkey
);
3043 ret
= _key_schedule(context
, dkey
);
3047 krb5_crypto_debug(context
, 1, block_sz
, dkey
->key
);
3049 ret
= (*et
->encrypt
)(context
, dkey
, p
, block_sz
, 1, usage
, ivec
);
3053 result
->length
= total_sz
;
3056 memset(p
, 0, total_sz
);
3062 static krb5_error_code
3063 encrypt_internal(krb5_context context
,
3070 size_t sz
, block_sz
, checksum_sz
;
3072 unsigned char *p
, *q
;
3073 krb5_error_code ret
;
3074 const struct encryption_type
*et
= crypto
->et
;
3076 checksum_sz
= CHECKSUMSIZE(et
->checksum
);
3078 sz
= et
->confoundersize
+ checksum_sz
+ len
;
3079 block_sz
= (sz
+ et
->padsize
- 1) &~ (et
->padsize
- 1); /* pad */
3080 p
= calloc(1, block_sz
);
3082 krb5_set_error_string(context
, "malloc: out of memory");
3087 krb5_generate_random_block(q
, et
->confoundersize
); /* XXX */
3088 q
+= et
->confoundersize
;
3089 memset(q
, 0, checksum_sz
);
3091 memcpy(q
, data
, len
);
3093 ret
= create_checksum(context
,
3100 if(ret
== 0 && cksum
.checksum
.length
!= checksum_sz
) {
3101 krb5_clear_error_string (context
);
3102 free_Checksum(&cksum
);
3103 ret
= KRB5_CRYPTO_INTERNAL
;
3107 memcpy(p
+ et
->confoundersize
, cksum
.checksum
.data
, cksum
.checksum
.length
);
3108 free_Checksum(&cksum
);
3109 ret
= _key_schedule(context
, &crypto
->key
);
3113 krb5_crypto_debug(context
, 1, block_sz
, crypto
->key
.key
);
3115 ret
= (*et
->encrypt
)(context
, &crypto
->key
, p
, block_sz
, 1, 0, ivec
);
3117 memset(p
, 0, block_sz
);
3122 result
->length
= block_sz
;
3125 memset(p
, 0, block_sz
);
3130 static krb5_error_code
3131 encrypt_internal_special(krb5_context context
,
3139 struct encryption_type
*et
= crypto
->et
;
3140 size_t cksum_sz
= CHECKSUMSIZE(et
->checksum
);
3141 size_t sz
= len
+ cksum_sz
+ et
->confoundersize
;
3143 krb5_error_code ret
;
3147 krb5_set_error_string(context
, "malloc: out of memory");
3151 memset (p
, 0, cksum_sz
);
3153 krb5_generate_random_block(p
, et
->confoundersize
);
3154 p
+= et
->confoundersize
;
3155 memcpy (p
, data
, len
);
3156 ret
= (*et
->encrypt
)(context
, &crypto
->key
, tmp
, sz
, TRUE
, usage
, ivec
);
3163 result
->length
= sz
;
3167 static krb5_error_code
3168 decrypt_internal_derived(krb5_context context
,
3179 krb5_error_code ret
;
3180 struct key_data
*dkey
;
3181 struct encryption_type
*et
= crypto
->et
;
3184 checksum_sz
= CHECKSUMSIZE(et
->keyed_checksum
);
3185 if (len
< checksum_sz
+ et
->confoundersize
) {
3186 krb5_set_error_string(context
, "Encrypted data shorter then "
3187 "checksum + confunder");
3188 return KRB5_BAD_MSIZE
;
3191 if (((len
- checksum_sz
) % et
->padsize
) != 0) {
3192 krb5_clear_error_string(context
);
3193 return KRB5_BAD_MSIZE
;
3197 if(len
!= 0 && p
== NULL
) {
3198 krb5_set_error_string(context
, "malloc: out of memory");
3201 memcpy(p
, data
, len
);
3205 ret
= _get_derived_key(context
, crypto
, ENCRYPTION_USAGE(usage
), &dkey
);
3210 ret
= _key_schedule(context
, dkey
);
3216 krb5_crypto_debug(context
, 0, len
, dkey
->key
);
3218 ret
= (*et
->encrypt
)(context
, dkey
, p
, len
, 0, usage
, ivec
);
3224 cksum
.checksum
.data
= p
+ len
;
3225 cksum
.checksum
.length
= checksum_sz
;
3226 cksum
.cksumtype
= CHECKSUMTYPE(et
->keyed_checksum
);
3228 ret
= verify_checksum(context
,
3230 INTEGRITY_USAGE(usage
),
3238 l
= len
- et
->confoundersize
;
3239 memmove(p
, p
+ et
->confoundersize
, l
);
3240 result
->data
= realloc(p
, l
);
3241 if(result
->data
== NULL
&& l
!= 0) {
3243 krb5_set_error_string(context
, "malloc: out of memory");
3250 static krb5_error_code
3251 decrypt_internal(krb5_context context
,
3258 krb5_error_code ret
;
3261 size_t checksum_sz
, l
;
3262 struct encryption_type
*et
= crypto
->et
;
3264 if ((len
% et
->padsize
) != 0) {
3265 krb5_clear_error_string(context
);
3266 return KRB5_BAD_MSIZE
;
3269 checksum_sz
= CHECKSUMSIZE(et
->checksum
);
3271 if(len
!= 0 && p
== NULL
) {
3272 krb5_set_error_string(context
, "malloc: out of memory");
3275 memcpy(p
, data
, len
);
3277 ret
= _key_schedule(context
, &crypto
->key
);
3283 krb5_crypto_debug(context
, 0, len
, crypto
->key
.key
);
3285 ret
= (*et
->encrypt
)(context
, &crypto
->key
, p
, len
, 0, 0, ivec
);
3290 ret
= krb5_data_copy(&cksum
.checksum
, p
+ et
->confoundersize
, checksum_sz
);
3295 memset(p
+ et
->confoundersize
, 0, checksum_sz
);
3296 cksum
.cksumtype
= CHECKSUMTYPE(et
->checksum
);
3297 ret
= verify_checksum(context
, NULL
, 0, p
, len
, &cksum
);
3298 free_Checksum(&cksum
);
3303 l
= len
- et
->confoundersize
- checksum_sz
;
3304 memmove(p
, p
+ et
->confoundersize
+ checksum_sz
, l
);
3305 result
->data
= realloc(p
, l
);
3306 if(result
->data
== NULL
&& l
!= 0) {
3308 krb5_set_error_string(context
, "malloc: out of memory");
3315 static krb5_error_code
3316 decrypt_internal_special(krb5_context context
,
3324 struct encryption_type
*et
= crypto
->et
;
3325 size_t cksum_sz
= CHECKSUMSIZE(et
->checksum
);
3326 size_t sz
= len
- cksum_sz
- et
->confoundersize
;
3328 krb5_error_code ret
;
3330 if ((len
% et
->padsize
) != 0) {
3331 krb5_clear_error_string(context
);
3332 return KRB5_BAD_MSIZE
;
3337 krb5_set_error_string(context
, "malloc: out of memory");
3340 memcpy(p
, data
, len
);
3342 ret
= (*et
->encrypt
)(context
, &crypto
->key
, p
, len
, FALSE
, usage
, ivec
);
3348 memmove (p
, p
+ cksum_sz
+ et
->confoundersize
, sz
);
3349 result
->data
= realloc(p
, sz
);
3350 if(result
->data
== NULL
&& sz
!= 0) {
3352 krb5_set_error_string(context
, "malloc: out of memory");
3355 result
->length
= sz
;
3360 krb5_error_code KRB5_LIB_FUNCTION
3361 krb5_encrypt_ivec(krb5_context context
,
3369 if(derived_crypto(context
, crypto
))
3370 return encrypt_internal_derived(context
, crypto
, usage
,
3371 data
, len
, result
, ivec
);
3372 else if (special_crypto(context
, crypto
))
3373 return encrypt_internal_special (context
, crypto
, usage
,
3374 data
, len
, result
, ivec
);
3376 return encrypt_internal(context
, crypto
, data
, len
, result
, ivec
);
3379 krb5_error_code KRB5_LIB_FUNCTION
3380 krb5_encrypt(krb5_context context
,
3387 return krb5_encrypt_ivec(context
, crypto
, usage
, data
, len
, result
, NULL
);
3390 krb5_error_code KRB5_LIB_FUNCTION
3391 krb5_encrypt_EncryptedData(krb5_context context
,
3397 EncryptedData
*result
)
3399 result
->etype
= CRYPTO_ETYPE(crypto
);
3401 ALLOC(result
->kvno
, 1);
3402 *result
->kvno
= kvno
;
3404 result
->kvno
= NULL
;
3405 return krb5_encrypt(context
, crypto
, usage
, data
, len
, &result
->cipher
);
3408 krb5_error_code KRB5_LIB_FUNCTION
3409 krb5_decrypt_ivec(krb5_context context
,
3417 if(derived_crypto(context
, crypto
))
3418 return decrypt_internal_derived(context
, crypto
, usage
,
3419 data
, len
, result
, ivec
);
3420 else if (special_crypto (context
, crypto
))
3421 return decrypt_internal_special(context
, crypto
, usage
,
3422 data
, len
, result
, ivec
);
3424 return decrypt_internal(context
, crypto
, data
, len
, result
, ivec
);
3427 krb5_error_code KRB5_LIB_FUNCTION
3428 krb5_decrypt(krb5_context context
,
3435 return krb5_decrypt_ivec (context
, crypto
, usage
, data
, len
, result
,
3439 krb5_error_code KRB5_LIB_FUNCTION
3440 krb5_decrypt_EncryptedData(krb5_context context
,
3443 const EncryptedData
*e
,
3446 return krb5_decrypt(context
, crypto
, usage
,
3447 e
->cipher
.data
, e
->cipher
.length
, result
);
3450 /************************************************************
3452 ************************************************************/
3454 #define ENTROPY_NEEDED 128
3457 seed_something(void)
3459 char buf
[1024], seedfile
[256];
3461 /* If there is a seed file, load it. But such a file cannot be trusted,
3462 so use 0 for the entropy estimate */
3463 if (RAND_file_name(seedfile
, sizeof(seedfile
))) {
3465 fd
= open(seedfile
, O_RDONLY
);
3468 ret
= read(fd
, buf
, sizeof(buf
));
3470 RAND_add(buf
, ret
, 0.0);
3477 /* Calling RAND_status() will try to use /dev/urandom if it exists so
3478 we do not have to deal with it. */
3479 if (RAND_status() != 1) {
3480 krb5_context context
;
3484 if (!krb5_init_context(&context
)) {
3485 p
= krb5_config_get_string(context
, NULL
, "libdefaults",
3486 "egd_socket", NULL
);
3488 RAND_egd_bytes(p
, ENTROPY_NEEDED
);
3489 krb5_free_context(context
);
3493 if (RAND_status() == 1) {
3494 /* Update the seed file */
3496 RAND_write_file(seedfile
);
3503 void KRB5_LIB_FUNCTION
3504 krb5_generate_random_block(void *buf
, size_t len
)
3506 static int rng_initialized
= 0;
3508 HEIMDAL_MUTEX_lock(&crypto_mutex
);
3509 if (!rng_initialized
) {
3510 if (seed_something())
3511 krb5_abortx(NULL
, "Fatal: could not seed the "
3512 "random number generator");
3514 rng_initialized
= 1;
3516 HEIMDAL_MUTEX_unlock(&crypto_mutex
);
3517 if (RAND_bytes(buf
, len
) != 1)
3518 krb5_abortx(NULL
, "Failed to generate random block");
3522 DES3_postproc(krb5_context context
,
3523 unsigned char *k
, size_t len
, struct key_data
*key
)
3525 DES3_random_to_key(context
, key
->key
, k
, len
);
3527 if (key
->schedule
) {
3528 krb5_free_data(context
, key
->schedule
);
3529 key
->schedule
= NULL
;
3533 static krb5_error_code
3534 derive_key(krb5_context context
,
3535 struct encryption_type
*et
,
3536 struct key_data
*key
,
3537 const void *constant
,
3541 unsigned int nblocks
= 0, i
;
3542 krb5_error_code ret
= 0;
3543 struct key_type
*kt
= et
->keytype
;
3545 ret
= _key_schedule(context
, key
);
3548 if(et
->blocksize
* 8 < kt
->bits
|| len
!= et
->blocksize
) {
3549 nblocks
= (kt
->bits
+ et
->blocksize
* 8 - 1) / (et
->blocksize
* 8);
3550 k
= malloc(nblocks
* et
->blocksize
);
3552 krb5_set_error_string(context
, "malloc: out of memory");
3555 ret
= _krb5_n_fold(constant
, len
, k
, et
->blocksize
);
3558 krb5_set_error_string(context
, "out of memory");
3561 for(i
= 0; i
< nblocks
; i
++) {
3563 memcpy(k
+ i
* et
->blocksize
,
3564 k
+ (i
- 1) * et
->blocksize
,
3566 (*et
->encrypt
)(context
, key
, k
+ i
* et
->blocksize
, et
->blocksize
,
3570 /* this case is probably broken, but won't be run anyway */
3571 void *c
= malloc(len
);
3572 size_t res_len
= (kt
->bits
+ 7) / 8;
3574 if(len
!= 0 && c
== NULL
) {
3575 krb5_set_error_string(context
, "malloc: out of memory");
3578 memcpy(c
, constant
, len
);
3579 (*et
->encrypt
)(context
, key
, c
, len
, 1, 0, NULL
);
3580 k
= malloc(res_len
);
3581 if(res_len
!= 0 && k
== NULL
) {
3583 krb5_set_error_string(context
, "malloc: out of memory");
3586 ret
= _krb5_n_fold(c
, len
, k
, res_len
);
3589 krb5_set_error_string(context
, "out of memory");
3595 /* XXX keytype dependent post-processing */
3598 DES3_postproc(context
, k
, nblocks
* et
->blocksize
, key
);
3600 case KEYTYPE_AES128
:
3601 case KEYTYPE_AES256
:
3602 memcpy(key
->key
->keyvalue
.data
, k
, key
->key
->keyvalue
.length
);
3605 krb5_set_error_string(context
,
3606 "derive_key() called with unknown keytype (%u)",
3608 ret
= KRB5_CRYPTO_INTERNAL
;
3611 if (key
->schedule
) {
3612 krb5_free_data(context
, key
->schedule
);
3613 key
->schedule
= NULL
;
3615 memset(k
, 0, nblocks
* et
->blocksize
);
3620 static struct key_data
*
3621 _new_derived_key(krb5_crypto crypto
, unsigned usage
)
3623 struct key_usage
*d
= crypto
->key_usage
;
3624 d
= realloc(d
, (crypto
->num_key_usage
+ 1) * sizeof(*d
));
3627 crypto
->key_usage
= d
;
3628 d
+= crypto
->num_key_usage
++;
3629 memset(d
, 0, sizeof(*d
));
3634 krb5_error_code KRB5_LIB_FUNCTION
3635 krb5_derive_key(krb5_context context
,
3636 const krb5_keyblock
*key
,
3638 const void *constant
,
3639 size_t constant_len
,
3640 krb5_keyblock
**derived_key
)
3642 krb5_error_code ret
;
3643 struct encryption_type
*et
;
3646 *derived_key
= NULL
;
3648 et
= _find_enctype (etype
);
3650 krb5_set_error_string(context
, "encryption type %d not supported",
3652 return KRB5_PROG_ETYPE_NOSUPP
;
3655 ret
= krb5_copy_keyblock(context
, key
, &d
.key
);
3660 ret
= derive_key(context
, et
, &d
, constant
, constant_len
);
3662 ret
= krb5_copy_keyblock(context
, d
.key
, derived_key
);
3663 free_key_data(context
, &d
);
3667 static krb5_error_code
3668 _get_derived_key(krb5_context context
,
3671 struct key_data
**key
)
3675 unsigned char constant
[5];
3677 for(i
= 0; i
< crypto
->num_key_usage
; i
++)
3678 if(crypto
->key_usage
[i
].usage
== usage
) {
3679 *key
= &crypto
->key_usage
[i
].key
;
3682 d
= _new_derived_key(crypto
, usage
);
3684 krb5_set_error_string(context
, "malloc: out of memory");
3687 krb5_copy_keyblock(context
, crypto
->key
.key
, &d
->key
);
3688 _krb5_put_int(constant
, usage
, 5);
3689 derive_key(context
, crypto
->et
, d
, constant
, sizeof(constant
));
3695 krb5_error_code KRB5_LIB_FUNCTION
3696 krb5_crypto_init(krb5_context context
,
3697 const krb5_keyblock
*key
,
3699 krb5_crypto
*crypto
)
3701 krb5_error_code ret
;
3703 if(*crypto
== NULL
) {
3704 krb5_set_error_string(context
, "malloc: out of memory");
3707 if(etype
== ETYPE_NULL
)
3708 etype
= key
->keytype
;
3709 (*crypto
)->et
= _find_enctype(etype
);
3710 if((*crypto
)->et
== NULL
|| ((*crypto
)->et
->flags
& F_DISABLED
)) {
3713 krb5_set_error_string (context
, "encryption type %d not supported",
3715 return KRB5_PROG_ETYPE_NOSUPP
;
3717 if((*crypto
)->et
->keytype
->size
!= key
->keyvalue
.length
) {
3720 krb5_set_error_string (context
, "encryption key has bad length");
3721 return KRB5_BAD_KEYSIZE
;
3723 ret
= krb5_copy_keyblock(context
, key
, &(*crypto
)->key
.key
);
3729 (*crypto
)->key
.schedule
= NULL
;
3730 (*crypto
)->num_key_usage
= 0;
3731 (*crypto
)->key_usage
= NULL
;
3736 free_key_data(krb5_context context
, struct key_data
*key
)
3738 krb5_free_keyblock(context
, key
->key
);
3740 memset(key
->schedule
->data
, 0, key
->schedule
->length
);
3741 krb5_free_data(context
, key
->schedule
);
3746 free_key_usage(krb5_context context
, struct key_usage
*ku
)
3748 free_key_data(context
, &ku
->key
);
3751 krb5_error_code KRB5_LIB_FUNCTION
3752 krb5_crypto_destroy(krb5_context context
,
3757 for(i
= 0; i
< crypto
->num_key_usage
; i
++)
3758 free_key_usage(context
, &crypto
->key_usage
[i
]);
3759 free(crypto
->key_usage
);
3760 free_key_data(context
, &crypto
->key
);
3765 krb5_error_code KRB5_LIB_FUNCTION
3766 krb5_crypto_getblocksize(krb5_context context
,
3770 *blocksize
= crypto
->et
->blocksize
;
3774 krb5_error_code KRB5_LIB_FUNCTION
3775 krb5_crypto_getenctype(krb5_context context
,
3777 krb5_enctype
*enctype
)
3779 *enctype
= crypto
->et
->type
;
3783 krb5_error_code KRB5_LIB_FUNCTION
3784 krb5_crypto_getpadsize(krb5_context context
,
3788 *padsize
= crypto
->et
->padsize
;
3792 krb5_error_code KRB5_LIB_FUNCTION
3793 krb5_crypto_getconfoundersize(krb5_context context
,
3795 size_t *confoundersize
)
3797 *confoundersize
= crypto
->et
->confoundersize
;
3801 krb5_error_code KRB5_LIB_FUNCTION
3802 krb5_enctype_disable(krb5_context context
,
3803 krb5_enctype enctype
)
3805 struct encryption_type
*et
= _find_enctype(enctype
);
3808 krb5_set_error_string (context
, "encryption type %d not supported",
3810 return KRB5_PROG_ETYPE_NOSUPP
;
3812 et
->flags
|= F_DISABLED
;
3816 krb5_error_code KRB5_LIB_FUNCTION
3817 krb5_string_to_key_derived(krb5_context context
,
3823 struct encryption_type
*et
= _find_enctype(etype
);
3824 krb5_error_code ret
;
3830 krb5_set_error_string (context
, "encryption type %d not supported",
3832 return KRB5_PROG_ETYPE_NOSUPP
;
3834 keylen
= et
->keytype
->bits
/ 8;
3837 if(kd
.key
== NULL
) {
3838 krb5_set_error_string (context
, "malloc: out of memory");
3841 ret
= krb5_data_alloc(&kd
.key
->keyvalue
, et
->keytype
->size
);
3846 kd
.key
->keytype
= etype
;
3847 tmp
= malloc (keylen
);
3849 krb5_free_keyblock(context
, kd
.key
);
3850 krb5_set_error_string (context
, "malloc: out of memory");
3853 ret
= _krb5_n_fold(str
, len
, tmp
, keylen
);
3856 krb5_set_error_string(context
, "out of memory");
3860 DES3_postproc (context
, tmp
, keylen
, &kd
); /* XXX */
3861 memset(tmp
, 0, keylen
);
3863 ret
= derive_key(context
,
3866 "kerberos", /* XXX well known constant */
3867 strlen("kerberos"));
3868 ret
= krb5_copy_keyblock_contents(context
, kd
.key
, key
);
3869 free_key_data(context
, &kd
);
3874 wrapped_length (krb5_context context
,
3878 struct encryption_type
*et
= crypto
->et
;
3879 size_t padsize
= et
->padsize
;
3880 size_t checksumsize
= CHECKSUMSIZE(et
->checksum
);
3883 res
= et
->confoundersize
+ checksumsize
+ data_len
;
3884 res
= (res
+ padsize
- 1) / padsize
* padsize
;
3889 wrapped_length_dervied (krb5_context context
,
3893 struct encryption_type
*et
= crypto
->et
;
3894 size_t padsize
= et
->padsize
;
3897 res
= et
->confoundersize
+ data_len
;
3898 res
= (res
+ padsize
- 1) / padsize
* padsize
;
3899 if (et
->keyed_checksum
)
3900 res
+= et
->keyed_checksum
->checksumsize
;
3902 res
+= et
->checksum
->checksumsize
;
3907 * Return the size of an encrypted packet of length `data_len'
3911 krb5_get_wrapped_length (krb5_context context
,
3915 if (derived_crypto (context
, crypto
))
3916 return wrapped_length_dervied (context
, crypto
, data_len
);
3918 return wrapped_length (context
, crypto
, data_len
);
3922 * Return the size of an encrypted packet of length `data_len'
3926 crypto_overhead (krb5_context context
,
3929 struct encryption_type
*et
= crypto
->et
;
3932 res
= CHECKSUMSIZE(et
->checksum
);
3933 res
+= et
->confoundersize
;
3934 if (et
->padsize
> 1)
3940 crypto_overhead_dervied (krb5_context context
,
3943 struct encryption_type
*et
= crypto
->et
;
3946 if (et
->keyed_checksum
)
3947 res
= CHECKSUMSIZE(et
->keyed_checksum
);
3949 res
= CHECKSUMSIZE(et
->checksum
);
3950 res
+= et
->confoundersize
;
3951 if (et
->padsize
> 1)
3957 krb5_crypto_overhead (krb5_context context
, krb5_crypto crypto
)
3959 if (derived_crypto (context
, crypto
))
3960 return crypto_overhead_dervied (context
, crypto
);
3962 return crypto_overhead (context
, crypto
);
3965 krb5_error_code KRB5_LIB_FUNCTION
3966 krb5_random_to_key(krb5_context context
,
3972 krb5_error_code ret
;
3973 struct encryption_type
*et
= _find_enctype(type
);
3975 krb5_set_error_string(context
, "encryption type %d not supported",
3977 return KRB5_PROG_ETYPE_NOSUPP
;
3979 if ((et
->keytype
->bits
+ 7) / 8 > size
) {
3980 krb5_set_error_string(context
, "encryption key %s needs %d bytes "
3981 "of random to make an encryption key out of it",
3982 et
->name
, (int)et
->keytype
->size
);
3983 return KRB5_PROG_ETYPE_NOSUPP
;
3985 ret
= krb5_data_alloc(&key
->keyvalue
, et
->keytype
->size
);
3988 key
->keytype
= type
;
3989 if (et
->keytype
->random_to_key
)
3990 (*et
->keytype
->random_to_key
)(context
, key
, data
, size
);
3992 memcpy(key
->keyvalue
.data
, data
, et
->keytype
->size
);
3998 _krb5_pk_octetstring2key(krb5_context context
,
4002 const heim_octet_string
*c_n
,
4003 const heim_octet_string
*k_n
,
4006 struct encryption_type
*et
= _find_enctype(type
);
4007 krb5_error_code ret
;
4008 size_t keylen
, offset
;
4010 unsigned char counter
;
4011 unsigned char shaoutput
[20];
4014 krb5_set_error_string(context
, "encryption type %d not supported",
4016 return KRB5_PROG_ETYPE_NOSUPP
;
4018 keylen
= (et
->keytype
->bits
+ 7) / 8;
4020 keydata
= malloc(keylen
);
4021 if (keydata
== NULL
) {
4022 krb5_set_error_string(context
, "malloc: out of memory");
4032 SHA1_Update(&m
, &counter
, 1);
4033 SHA1_Update(&m
, dhdata
, dhsize
);
4035 SHA1_Update(&m
, c_n
->data
, c_n
->length
);
4037 SHA1_Update(&m
, k_n
->data
, k_n
->length
);
4038 SHA1_Final(shaoutput
, &m
);
4040 memcpy((unsigned char *)keydata
+ offset
,
4042 min(keylen
- offset
, sizeof(shaoutput
)));
4044 offset
+= sizeof(shaoutput
);
4046 } while(offset
< keylen
);
4047 memset(shaoutput
, 0, sizeof(shaoutput
));
4049 ret
= krb5_random_to_key(context
, type
, keydata
, keylen
, key
);
4050 memset(keydata
, 0, sizeof(keylen
));
4055 krb5_error_code KRB5_LIB_FUNCTION
4056 krb5_crypto_prf_length(krb5_context context
,
4060 struct encryption_type
*et
= _find_enctype(type
);
4062 if(et
== NULL
|| et
->prf_length
== 0) {
4063 krb5_set_error_string(context
, "encryption type %d not supported",
4065 return KRB5_PROG_ETYPE_NOSUPP
;
4068 *length
= et
->prf_length
;
4072 krb5_error_code KRB5_LIB_FUNCTION
4073 krb5_crypto_prf(krb5_context context
,
4074 const krb5_crypto crypto
,
4075 const krb5_data
*input
,
4078 struct encryption_type
*et
= crypto
->et
;
4080 krb5_data_zero(output
);
4082 if(et
->prf
== NULL
) {
4083 krb5_set_error_string(context
, "kerberos prf for %s not supported",
4085 return KRB5_PROG_ETYPE_NOSUPP
;
4088 return (*et
->prf
)(context
, crypto
, input
, output
);
4096 static krb5_error_code
4097 krb5_get_keyid(krb5_context context
,
4102 unsigned char tmp
[16];
4105 MD5_Update (&md5
, key
->keyvalue
.data
, key
->keyvalue
.length
);
4106 MD5_Final (tmp
, &md5
);
4107 *keyid
= (tmp
[12] << 24) | (tmp
[13] << 16) | (tmp
[14] << 8) | tmp
[15];
4112 krb5_crypto_debug(krb5_context context
,
4119 krb5_get_keyid(context
, key
, &keyid
);
4120 krb5_enctype_to_string(context
, key
->keytype
, &kt
);
4121 krb5_warnx(context
, "%s %lu bytes with key-id %#x (%s)",
4122 encryptp
? "encrypting" : "decrypting",
4129 #endif /* CRYPTO_DEBUG */
4137 krb5_context context
;
4142 unsigned usage
= ENCRYPTION_USAGE(3);
4143 krb5_error_code ret
;
4145 ret
= krb5_init_context(&context
);
4147 errx (1, "krb5_init_context failed: %d", ret
);
4149 key
.keytype
= ETYPE_NEW_DES3_CBC_SHA1
;
4150 key
.keyvalue
.data
= "\xb3\x85\x58\x94\xd9\xdc\x7c\xc8"
4151 "\x25\xe9\x85\xab\x3e\xb5\xfb\x0e"
4152 "\xc8\xdf\xab\x26\x86\x64\x15\x25";
4153 key
.keyvalue
.length
= 24;
4155 krb5_crypto_init(context
, &key
, 0, &crypto
);
4157 d
= _new_derived_key(crypto
, usage
);
4159 krb5_errx(context
, 1, "_new_derived_key failed");
4160 krb5_copy_keyblock(context
, crypto
->key
.key
, &d
->key
);
4161 _krb5_put_int(constant
, usage
, 4);
4162 derive_key(context
, crypto
->et
, d
, constant
, sizeof(constant
));
4166 krb5_context context
;
4170 krb5_error_code ret
;
4173 char *data
= "what do ya want for nothing?";
4175 ret
= krb5_init_context(&context
);
4177 errx (1, "krb5_init_context failed: %d", ret
);
4179 key
.keytype
= ETYPE_NEW_DES3_CBC_SHA1
;
4180 key
.keyvalue
.data
= "Jefe";
4181 /* "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
4182 "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"; */
4183 key
.keyvalue
.length
= 4;
4185 d
= ecalloc(1, sizeof(*d
));
4187 res
.checksum
.length
= 20;
4188 res
.checksum
.data
= emalloc(res
.checksum
.length
);
4189 SP_HMAC_SHA1_checksum(context
, d
, data
, 28, &res
);