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"
36 #include <pkinit_asn1.h>
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_unchecked(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_unchecked (&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_unchecked (&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_unchecked(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_unchecked(&k
[0], &s
[0]);
395 DES_set_key_unchecked(&k
[1], &s
[1]);
396 DES_set_key_unchecked(&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_unchecked(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 krb5_error_code KRB5_LIB_FUNCTION
841 krb5_salttype_to_string (krb5_context context
,
846 struct encryption_type
*e
;
847 struct salt_type
*st
;
849 e
= _find_enctype (etype
);
851 krb5_set_error_string(context
, "encryption type %d not supported",
853 return KRB5_PROG_ETYPE_NOSUPP
;
855 for (st
= e
->keytype
->string_to_key
; st
&& st
->type
; st
++) {
856 if (st
->type
== stype
) {
857 *string
= strdup (st
->name
);
858 if (*string
== NULL
) {
859 krb5_set_error_string(context
, "malloc: out of memory");
865 krb5_set_error_string(context
, "salttype %d not supported", stype
);
866 return HEIM_ERR_SALTTYPE_NOSUPP
;
869 krb5_error_code KRB5_LIB_FUNCTION
870 krb5_string_to_salttype (krb5_context context
,
873 krb5_salttype
*salttype
)
875 struct encryption_type
*e
;
876 struct salt_type
*st
;
878 e
= _find_enctype (etype
);
880 krb5_set_error_string(context
, "encryption type %d not supported",
882 return KRB5_PROG_ETYPE_NOSUPP
;
884 for (st
= e
->keytype
->string_to_key
; st
&& st
->type
; st
++) {
885 if (strcasecmp (st
->name
, string
) == 0) {
886 *salttype
= st
->type
;
890 krb5_set_error_string(context
, "salttype %s not supported", string
);
891 return HEIM_ERR_SALTTYPE_NOSUPP
;
894 krb5_error_code KRB5_LIB_FUNCTION
895 krb5_get_pw_salt(krb5_context context
,
896 krb5_const_principal principal
,
904 salt
->salttype
= KRB5_PW_SALT
;
905 len
= strlen(principal
->realm
);
906 for (i
= 0; i
< principal
->name
.name_string
.len
; ++i
)
907 len
+= strlen(principal
->name
.name_string
.val
[i
]);
908 ret
= krb5_data_alloc (&salt
->saltvalue
, len
);
911 p
= salt
->saltvalue
.data
;
912 memcpy (p
, principal
->realm
, strlen(principal
->realm
));
913 p
+= strlen(principal
->realm
);
914 for (i
= 0; i
< principal
->name
.name_string
.len
; ++i
) {
916 principal
->name
.name_string
.val
[i
],
917 strlen(principal
->name
.name_string
.val
[i
]));
918 p
+= strlen(principal
->name
.name_string
.val
[i
]);
923 krb5_error_code KRB5_LIB_FUNCTION
924 krb5_free_salt(krb5_context context
,
927 krb5_data_free(&salt
.saltvalue
);
931 krb5_error_code KRB5_LIB_FUNCTION
932 krb5_string_to_key_data (krb5_context context
,
933 krb5_enctype enctype
,
935 krb5_principal principal
,
941 ret
= krb5_get_pw_salt(context
, principal
, &salt
);
944 ret
= krb5_string_to_key_data_salt(context
, enctype
, password
, salt
, key
);
945 krb5_free_salt(context
, salt
);
949 krb5_error_code KRB5_LIB_FUNCTION
950 krb5_string_to_key (krb5_context context
,
951 krb5_enctype enctype
,
952 const char *password
,
953 krb5_principal principal
,
957 pw
.data
= rk_UNCONST(password
);
958 pw
.length
= strlen(password
);
959 return krb5_string_to_key_data(context
, enctype
, pw
, principal
, key
);
962 krb5_error_code KRB5_LIB_FUNCTION
963 krb5_string_to_key_data_salt (krb5_context context
,
964 krb5_enctype enctype
,
970 krb5_data_zero(&opaque
);
971 return krb5_string_to_key_data_salt_opaque(context
, enctype
, password
,
976 * Do a string -> key for encryption type `enctype' operation on
977 * `password' (with salt `salt' and the enctype specific data string
978 * `opaque'), returning the resulting key in `key'
981 krb5_error_code KRB5_LIB_FUNCTION
982 krb5_string_to_key_data_salt_opaque (krb5_context context
,
983 krb5_enctype enctype
,
989 struct encryption_type
*et
=_find_enctype(enctype
);
990 struct salt_type
*st
;
992 krb5_set_error_string(context
, "encryption type %d not supported",
994 return KRB5_PROG_ETYPE_NOSUPP
;
996 for(st
= et
->keytype
->string_to_key
; st
&& st
->type
; st
++)
997 if(st
->type
== salt
.salttype
)
998 return (*st
->string_to_key
)(context
, enctype
, password
,
1000 krb5_set_error_string(context
, "salt type %d not supported",
1002 return HEIM_ERR_SALTTYPE_NOSUPP
;
1006 * Do a string -> key for encryption type `enctype' operation on the
1007 * string `password' (with salt `salt'), returning the resulting key
1011 krb5_error_code KRB5_LIB_FUNCTION
1012 krb5_string_to_key_salt (krb5_context context
,
1013 krb5_enctype enctype
,
1014 const char *password
,
1019 pw
.data
= rk_UNCONST(password
);
1020 pw
.length
= strlen(password
);
1021 return krb5_string_to_key_data_salt(context
, enctype
, pw
, salt
, key
);
1024 krb5_error_code KRB5_LIB_FUNCTION
1025 krb5_string_to_key_salt_opaque (krb5_context context
,
1026 krb5_enctype enctype
,
1027 const char *password
,
1033 pw
.data
= rk_UNCONST(password
);
1034 pw
.length
= strlen(password
);
1035 return krb5_string_to_key_data_salt_opaque(context
, enctype
,
1036 pw
, salt
, opaque
, key
);
1039 krb5_error_code KRB5_LIB_FUNCTION
1040 krb5_keytype_to_string(krb5_context context
,
1041 krb5_keytype keytype
,
1044 struct key_type
*kt
= _find_keytype(keytype
);
1046 krb5_set_error_string(context
, "key type %d not supported", keytype
);
1047 return KRB5_PROG_KEYTYPE_NOSUPP
;
1049 *string
= strdup(kt
->name
);
1050 if(*string
== NULL
) {
1051 krb5_set_error_string(context
, "malloc: out of memory");
1057 krb5_error_code KRB5_LIB_FUNCTION
1058 krb5_string_to_keytype(krb5_context context
,
1060 krb5_keytype
*keytype
)
1063 for(i
= 0; i
< num_keytypes
; i
++)
1064 if(strcasecmp(keytypes
[i
]->name
, string
) == 0){
1065 *keytype
= keytypes
[i
]->type
;
1068 krb5_set_error_string(context
, "key type %s not supported", string
);
1069 return KRB5_PROG_KEYTYPE_NOSUPP
;
1072 krb5_error_code KRB5_LIB_FUNCTION
1073 krb5_enctype_keysize(krb5_context context
,
1077 struct encryption_type
*et
= _find_enctype(type
);
1079 krb5_set_error_string(context
, "encryption type %d not supported",
1081 return KRB5_PROG_ETYPE_NOSUPP
;
1083 *keysize
= et
->keytype
->size
;
1087 krb5_error_code KRB5_LIB_FUNCTION
1088 krb5_enctype_keybits(krb5_context context
,
1092 struct encryption_type
*et
= _find_enctype(type
);
1094 krb5_set_error_string(context
, "encryption type %d not supported",
1096 return KRB5_PROG_ETYPE_NOSUPP
;
1098 *keybits
= et
->keytype
->bits
;
1102 krb5_error_code KRB5_LIB_FUNCTION
1103 krb5_generate_random_keyblock(krb5_context context
,
1107 krb5_error_code ret
;
1108 struct encryption_type
*et
= _find_enctype(type
);
1110 krb5_set_error_string(context
, "encryption type %d not supported",
1112 return KRB5_PROG_ETYPE_NOSUPP
;
1114 ret
= krb5_data_alloc(&key
->keyvalue
, et
->keytype
->size
);
1117 key
->keytype
= type
;
1118 if(et
->keytype
->random_key
)
1119 (*et
->keytype
->random_key
)(context
, key
);
1121 krb5_generate_random_block(key
->keyvalue
.data
,
1122 key
->keyvalue
.length
);
1126 static krb5_error_code
1127 _key_schedule(krb5_context context
,
1128 struct key_data
*key
)
1130 krb5_error_code ret
;
1131 struct encryption_type
*et
= _find_enctype(key
->key
->keytype
);
1132 struct key_type
*kt
= et
->keytype
;
1134 if(kt
->schedule
== NULL
)
1136 if (key
->schedule
!= NULL
)
1138 ALLOC(key
->schedule
, 1);
1139 if(key
->schedule
== NULL
) {
1140 krb5_set_error_string(context
, "malloc: out of memory");
1143 ret
= krb5_data_alloc(key
->schedule
, kt
->schedule_size
);
1145 free(key
->schedule
);
1146 key
->schedule
= NULL
;
1149 (*kt
->schedule
)(context
, key
);
1153 /************************************************************
1155 ************************************************************/
1158 NONE_checksum(krb5_context context
,
1159 struct key_data
*key
,
1168 CRC32_checksum(krb5_context context
,
1169 struct key_data
*key
,
1176 unsigned char *r
= C
->checksum
.data
;
1177 _krb5_crc_init_table ();
1178 crc
= _krb5_crc_update (data
, len
, 0);
1180 r
[1] = (crc
>> 8) & 0xff;
1181 r
[2] = (crc
>> 16) & 0xff;
1182 r
[3] = (crc
>> 24) & 0xff;
1186 RSA_MD4_checksum(krb5_context context
,
1187 struct key_data
*key
,
1196 MD4_Update (&m
, data
, len
);
1197 MD4_Final (C
->checksum
.data
, &m
);
1201 RSA_MD4_DES_checksum(krb5_context context
,
1202 struct key_data
*key
,
1210 unsigned char *p
= cksum
->checksum
.data
;
1212 krb5_generate_random_block(p
, 8);
1214 MD4_Update (&md4
, p
, 8);
1215 MD4_Update (&md4
, data
, len
);
1216 MD4_Final (p
+ 8, &md4
);
1217 memset (&ivec
, 0, sizeof(ivec
));
1221 key
->schedule
->data
,
1226 static krb5_error_code
1227 RSA_MD4_DES_verify(krb5_context context
,
1228 struct key_data
*key
,
1235 unsigned char tmp
[24];
1236 unsigned char res
[16];
1238 krb5_error_code ret
= 0;
1240 memset(&ivec
, 0, sizeof(ivec
));
1241 DES_cbc_encrypt(C
->checksum
.data
,
1244 key
->schedule
->data
,
1248 MD4_Update (&md4
, tmp
, 8); /* confounder */
1249 MD4_Update (&md4
, data
, len
);
1250 MD4_Final (res
, &md4
);
1251 if(memcmp(res
, tmp
+ 8, sizeof(res
)) != 0) {
1252 krb5_clear_error_string (context
);
1253 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
1255 memset(tmp
, 0, sizeof(tmp
));
1256 memset(res
, 0, sizeof(res
));
1261 RSA_MD5_checksum(krb5_context context
,
1262 struct key_data
*key
,
1271 MD5_Update(&m
, data
, len
);
1272 MD5_Final (C
->checksum
.data
, &m
);
1276 RSA_MD5_DES_checksum(krb5_context context
,
1277 struct key_data
*key
,
1285 unsigned char *p
= C
->checksum
.data
;
1287 krb5_generate_random_block(p
, 8);
1289 MD5_Update (&md5
, p
, 8);
1290 MD5_Update (&md5
, data
, len
);
1291 MD5_Final (p
+ 8, &md5
);
1292 memset (&ivec
, 0, sizeof(ivec
));
1296 key
->schedule
->data
,
1301 static krb5_error_code
1302 RSA_MD5_DES_verify(krb5_context context
,
1303 struct key_data
*key
,
1310 unsigned char tmp
[24];
1311 unsigned char res
[16];
1313 DES_key_schedule
*sched
= key
->schedule
->data
;
1314 krb5_error_code ret
= 0;
1316 memset(&ivec
, 0, sizeof(ivec
));
1317 DES_cbc_encrypt(C
->checksum
.data
,
1324 MD5_Update (&md5
, tmp
, 8); /* confounder */
1325 MD5_Update (&md5
, data
, len
);
1326 MD5_Final (res
, &md5
);
1327 if(memcmp(res
, tmp
+ 8, sizeof(res
)) != 0) {
1328 krb5_clear_error_string (context
);
1329 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
1331 memset(tmp
, 0, sizeof(tmp
));
1332 memset(res
, 0, sizeof(res
));
1337 RSA_MD5_DES3_checksum(krb5_context context
,
1338 struct key_data
*key
,
1346 unsigned char *p
= C
->checksum
.data
;
1347 DES_key_schedule
*sched
= key
->schedule
->data
;
1349 krb5_generate_random_block(p
, 8);
1351 MD5_Update (&md5
, p
, 8);
1352 MD5_Update (&md5
, data
, len
);
1353 MD5_Final (p
+ 8, &md5
);
1354 memset (&ivec
, 0, sizeof(ivec
));
1355 DES_ede3_cbc_encrypt(p
,
1358 &sched
[0], &sched
[1], &sched
[2],
1363 static krb5_error_code
1364 RSA_MD5_DES3_verify(krb5_context context
,
1365 struct key_data
*key
,
1372 unsigned char tmp
[24];
1373 unsigned char res
[16];
1375 DES_key_schedule
*sched
= key
->schedule
->data
;
1376 krb5_error_code ret
= 0;
1378 memset(&ivec
, 0, sizeof(ivec
));
1379 DES_ede3_cbc_encrypt(C
->checksum
.data
,
1382 &sched
[0], &sched
[1], &sched
[2],
1386 MD5_Update (&md5
, tmp
, 8); /* confounder */
1387 MD5_Update (&md5
, data
, len
);
1388 MD5_Final (res
, &md5
);
1389 if(memcmp(res
, tmp
+ 8, sizeof(res
)) != 0) {
1390 krb5_clear_error_string (context
);
1391 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
1393 memset(tmp
, 0, sizeof(tmp
));
1394 memset(res
, 0, sizeof(res
));
1399 SHA1_checksum(krb5_context context
,
1400 struct key_data
*key
,
1409 SHA1_Update(&m
, data
, len
);
1410 SHA1_Final(C
->checksum
.data
, &m
);
1413 /* HMAC according to RFC2104 */
1414 static krb5_error_code
1415 hmac(krb5_context context
,
1416 struct checksum_type
*cm
,
1420 struct key_data
*keyblock
,
1423 unsigned char *ipad
, *opad
;
1428 ipad
= malloc(cm
->blocksize
+ len
);
1431 opad
= malloc(cm
->blocksize
+ cm
->checksumsize
);
1436 memset(ipad
, 0x36, cm
->blocksize
);
1437 memset(opad
, 0x5c, cm
->blocksize
);
1439 if(keyblock
->key
->keyvalue
.length
> cm
->blocksize
){
1440 (*cm
->checksum
)(context
,
1442 keyblock
->key
->keyvalue
.data
,
1443 keyblock
->key
->keyvalue
.length
,
1446 key
= result
->checksum
.data
;
1447 key_len
= result
->checksum
.length
;
1449 key
= keyblock
->key
->keyvalue
.data
;
1450 key_len
= keyblock
->key
->keyvalue
.length
;
1452 for(i
= 0; i
< key_len
; i
++){
1456 memcpy(ipad
+ cm
->blocksize
, data
, len
);
1457 (*cm
->checksum
)(context
, keyblock
, ipad
, cm
->blocksize
+ len
,
1459 memcpy(opad
+ cm
->blocksize
, result
->checksum
.data
,
1460 result
->checksum
.length
);
1461 (*cm
->checksum
)(context
, keyblock
, opad
,
1462 cm
->blocksize
+ cm
->checksumsize
, usage
, result
);
1463 memset(ipad
, 0, cm
->blocksize
+ len
);
1465 memset(opad
, 0, cm
->blocksize
+ cm
->checksumsize
);
1471 krb5_error_code KRB5_LIB_FUNCTION
1472 krb5_hmac(krb5_context context
,
1473 krb5_cksumtype cktype
,
1480 struct checksum_type
*c
= _find_checksum(cktype
);
1482 krb5_error_code ret
;
1485 krb5_set_error_string (context
, "checksum type %d not supported",
1487 return KRB5_PROG_SUMTYPE_NOSUPP
;
1493 ret
= hmac(context
, c
, data
, len
, usage
, &kd
, result
);
1496 krb5_free_data(context
, kd
.schedule
);
1502 SP_HMAC_SHA1_checksum(krb5_context context
,
1503 struct key_data
*key
,
1509 struct checksum_type
*c
= _find_checksum(CKSUMTYPE_SHA1
);
1512 krb5_error_code ret
;
1514 res
.checksum
.data
= sha1_data
;
1515 res
.checksum
.length
= sizeof(sha1_data
);
1517 ret
= hmac(context
, c
, data
, len
, usage
, key
, &res
);
1519 krb5_abortx(context
, "hmac failed");
1520 memcpy(result
->checksum
.data
, res
.checksum
.data
, result
->checksum
.length
);
1524 * checksum according to section 5. of draft-brezak-win2k-krb-rc4-hmac-03.txt
1528 HMAC_MD5_checksum(krb5_context context
,
1529 struct key_data
*key
,
1536 struct checksum_type
*c
= _find_checksum (CKSUMTYPE_RSA_MD5
);
1537 const char signature
[] = "signaturekey";
1539 struct key_data ksign
;
1542 unsigned char tmp
[16];
1543 unsigned char ksign_c_data
[16];
1544 krb5_error_code ret
;
1546 ksign_c
.checksum
.length
= sizeof(ksign_c_data
);
1547 ksign_c
.checksum
.data
= ksign_c_data
;
1548 ret
= hmac(context
, c
, signature
, sizeof(signature
), 0, key
, &ksign_c
);
1550 krb5_abortx(context
, "hmac failed");
1552 kb
.keyvalue
= ksign_c
.checksum
;
1554 t
[0] = (usage
>> 0) & 0xFF;
1555 t
[1] = (usage
>> 8) & 0xFF;
1556 t
[2] = (usage
>> 16) & 0xFF;
1557 t
[3] = (usage
>> 24) & 0xFF;
1558 MD5_Update (&md5
, t
, 4);
1559 MD5_Update (&md5
, data
, len
);
1560 MD5_Final (tmp
, &md5
);
1561 ret
= hmac(context
, c
, tmp
, sizeof(tmp
), 0, &ksign
, result
);
1563 krb5_abortx(context
, "hmac failed");
1567 * same as previous but being used while encrypting.
1571 HMAC_MD5_checksum_enc(krb5_context context
,
1572 struct key_data
*key
,
1578 struct checksum_type
*c
= _find_checksum (CKSUMTYPE_RSA_MD5
);
1580 struct key_data ksign
;
1583 unsigned char ksign_c_data
[16];
1584 krb5_error_code ret
;
1586 t
[0] = (usage
>> 0) & 0xFF;
1587 t
[1] = (usage
>> 8) & 0xFF;
1588 t
[2] = (usage
>> 16) & 0xFF;
1589 t
[3] = (usage
>> 24) & 0xFF;
1591 ksign_c
.checksum
.length
= sizeof(ksign_c_data
);
1592 ksign_c
.checksum
.data
= ksign_c_data
;
1593 ret
= hmac(context
, c
, t
, sizeof(t
), 0, key
, &ksign_c
);
1595 krb5_abortx(context
, "hmac failed");
1597 kb
.keyvalue
= ksign_c
.checksum
;
1598 ret
= hmac(context
, c
, data
, len
, 0, &ksign
, result
);
1600 krb5_abortx(context
, "hmac failed");
1603 static struct checksum_type checksum_none
= {
1612 static struct checksum_type checksum_crc32
= {
1621 static struct checksum_type checksum_rsa_md4
= {
1630 static struct checksum_type checksum_rsa_md4_des
= {
1631 CKSUMTYPE_RSA_MD4_DES
,
1635 F_KEYED
| F_CPROOF
| F_VARIANT
,
1636 RSA_MD4_DES_checksum
,
1640 static struct checksum_type checksum_des_mac
= {
1648 static struct checksum_type checksum_des_mac_k
= {
1649 CKSUMTYPE_DES_MAC_K
,
1656 static struct checksum_type checksum_rsa_md4_des_k
= {
1657 CKSUMTYPE_RSA_MD4_DES_K
,
1662 RSA_MD4_DES_K_checksum
,
1663 RSA_MD4_DES_K_verify
1666 static struct checksum_type checksum_rsa_md5
= {
1675 static struct checksum_type checksum_rsa_md5_des
= {
1676 CKSUMTYPE_RSA_MD5_DES
,
1680 F_KEYED
| F_CPROOF
| F_VARIANT
,
1681 RSA_MD5_DES_checksum
,
1684 static struct checksum_type checksum_rsa_md5_des3
= {
1685 CKSUMTYPE_RSA_MD5_DES3
,
1689 F_KEYED
| F_CPROOF
| F_VARIANT
,
1690 RSA_MD5_DES3_checksum
,
1693 static struct checksum_type checksum_sha1
= {
1702 static struct checksum_type checksum_hmac_sha1_des3
= {
1703 CKSUMTYPE_HMAC_SHA1_DES3
,
1707 F_KEYED
| F_CPROOF
| F_DERIVED
,
1708 SP_HMAC_SHA1_checksum
,
1712 static struct checksum_type checksum_hmac_sha1_aes128
= {
1713 CKSUMTYPE_HMAC_SHA1_96_AES_128
,
1714 "hmac-sha1-96-aes128",
1717 F_KEYED
| F_CPROOF
| F_DERIVED
,
1718 SP_HMAC_SHA1_checksum
,
1722 static struct checksum_type checksum_hmac_sha1_aes256
= {
1723 CKSUMTYPE_HMAC_SHA1_96_AES_256
,
1724 "hmac-sha1-96-aes256",
1727 F_KEYED
| F_CPROOF
| F_DERIVED
,
1728 SP_HMAC_SHA1_checksum
,
1732 static struct checksum_type checksum_hmac_md5
= {
1742 static struct checksum_type checksum_hmac_md5_enc
= {
1743 CKSUMTYPE_HMAC_MD5_ENC
,
1747 F_KEYED
| F_CPROOF
| F_PSEUDO
,
1748 HMAC_MD5_checksum_enc
,
1752 static struct checksum_type
*checksum_types
[] = {
1756 &checksum_rsa_md4_des
,
1759 &checksum_des_mac_k
,
1760 &checksum_rsa_md4_des_k
,
1763 &checksum_rsa_md5_des
,
1764 &checksum_rsa_md5_des3
,
1766 &checksum_hmac_sha1_des3
,
1767 &checksum_hmac_sha1_aes128
,
1768 &checksum_hmac_sha1_aes256
,
1770 &checksum_hmac_md5_enc
1773 static int num_checksums
= sizeof(checksum_types
) / sizeof(checksum_types
[0]);
1775 static struct checksum_type
*
1776 _find_checksum(krb5_cksumtype type
)
1779 for(i
= 0; i
< num_checksums
; i
++)
1780 if(checksum_types
[i
]->type
== type
)
1781 return checksum_types
[i
];
1785 static krb5_error_code
1786 get_checksum_key(krb5_context context
,
1788 unsigned usage
, /* not krb5_key_usage */
1789 struct checksum_type
*ct
,
1790 struct key_data
**key
)
1792 krb5_error_code ret
= 0;
1794 if(ct
->flags
& F_DERIVED
)
1795 ret
= _get_derived_key(context
, crypto
, usage
, key
);
1796 else if(ct
->flags
& F_VARIANT
) {
1799 *key
= _new_derived_key(crypto
, 0xff/* KRB5_KU_RFC1510_VARIANT */);
1801 krb5_set_error_string(context
, "malloc: out of memory");
1804 ret
= krb5_copy_keyblock(context
, crypto
->key
.key
, &(*key
)->key
);
1807 for(i
= 0; i
< (*key
)->key
->keyvalue
.length
; i
++)
1808 ((unsigned char*)(*key
)->key
->keyvalue
.data
)[i
] ^= 0xF0;
1810 *key
= &crypto
->key
;
1813 ret
= _key_schedule(context
, *key
);
1817 static krb5_error_code
1818 create_checksum (krb5_context context
,
1819 struct checksum_type
*ct
,
1826 krb5_error_code ret
;
1827 struct key_data
*dkey
;
1830 if (ct
->flags
& F_DISABLED
) {
1831 krb5_clear_error_string (context
);
1832 return KRB5_PROG_SUMTYPE_NOSUPP
;
1834 keyed_checksum
= (ct
->flags
& F_KEYED
) != 0;
1835 if(keyed_checksum
&& crypto
== NULL
) {
1836 krb5_set_error_string (context
, "Checksum type %s is keyed "
1837 "but no crypto context (key) was passed in",
1839 return KRB5_PROG_SUMTYPE_NOSUPP
; /* XXX */
1841 if(keyed_checksum
) {
1842 ret
= get_checksum_key(context
, crypto
, usage
, ct
, &dkey
);
1847 result
->cksumtype
= ct
->type
;
1848 ret
= krb5_data_alloc(&result
->checksum
, ct
->checksumsize
);
1851 (*ct
->checksum
)(context
, dkey
, data
, len
, usage
, result
);
1856 arcfour_checksum_p(struct checksum_type
*ct
, krb5_crypto crypto
)
1858 return (ct
->type
== CKSUMTYPE_HMAC_MD5
) &&
1859 (crypto
->key
.key
->keytype
== KEYTYPE_ARCFOUR
);
1862 krb5_error_code KRB5_LIB_FUNCTION
1863 krb5_create_checksum(krb5_context context
,
1865 krb5_key_usage usage
,
1871 struct checksum_type
*ct
= NULL
;
1874 /* type 0 -> pick from crypto */
1876 ct
= _find_checksum(type
);
1877 } else if (crypto
) {
1878 ct
= crypto
->et
->keyed_checksum
;
1880 ct
= crypto
->et
->checksum
;
1884 krb5_set_error_string (context
, "checksum type %d not supported",
1886 return KRB5_PROG_SUMTYPE_NOSUPP
;
1889 if (arcfour_checksum_p(ct
, crypto
)) {
1891 usage2arcfour(context
, &keyusage
);
1893 keyusage
= CHECKSUM_USAGE(usage
);
1895 return create_checksum(context
, ct
, crypto
, keyusage
,
1899 static krb5_error_code
1900 verify_checksum(krb5_context context
,
1902 unsigned usage
, /* not krb5_key_usage */
1907 krb5_error_code ret
;
1908 struct key_data
*dkey
;
1911 struct checksum_type
*ct
;
1913 ct
= _find_checksum(cksum
->cksumtype
);
1914 if (ct
== NULL
|| (ct
->flags
& F_DISABLED
)) {
1915 krb5_set_error_string (context
, "checksum type %d not supported",
1917 return KRB5_PROG_SUMTYPE_NOSUPP
;
1919 if(ct
->checksumsize
!= cksum
->checksum
.length
) {
1920 krb5_clear_error_string (context
);
1921 return KRB5KRB_AP_ERR_BAD_INTEGRITY
; /* XXX */
1923 keyed_checksum
= (ct
->flags
& F_KEYED
) != 0;
1924 if(keyed_checksum
&& crypto
== NULL
) {
1925 krb5_set_error_string (context
, "Checksum type %s is keyed "
1926 "but no crypto context (key) was passed in",
1928 return KRB5_PROG_SUMTYPE_NOSUPP
; /* XXX */
1931 ret
= get_checksum_key(context
, crypto
, usage
, ct
, &dkey
);
1935 return (*ct
->verify
)(context
, dkey
, data
, len
, usage
, cksum
);
1937 ret
= krb5_data_alloc (&c
.checksum
, ct
->checksumsize
);
1941 (*ct
->checksum
)(context
, dkey
, data
, len
, usage
, &c
);
1943 if(c
.checksum
.length
!= cksum
->checksum
.length
||
1944 memcmp(c
.checksum
.data
, cksum
->checksum
.data
, c
.checksum
.length
)) {
1945 krb5_clear_error_string (context
);
1946 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
1950 krb5_data_free (&c
.checksum
);
1954 krb5_error_code KRB5_LIB_FUNCTION
1955 krb5_verify_checksum(krb5_context context
,
1957 krb5_key_usage usage
,
1962 struct checksum_type
*ct
;
1965 ct
= _find_checksum(cksum
->cksumtype
);
1967 krb5_set_error_string (context
, "checksum type %d not supported",
1969 return KRB5_PROG_SUMTYPE_NOSUPP
;
1972 if (arcfour_checksum_p(ct
, crypto
)) {
1974 usage2arcfour(context
, &keyusage
);
1976 keyusage
= CHECKSUM_USAGE(usage
);
1978 return verify_checksum(context
, crypto
, keyusage
,
1982 krb5_error_code KRB5_LIB_FUNCTION
1983 krb5_crypto_get_checksum_type(krb5_context context
,
1985 krb5_cksumtype
*type
)
1987 struct checksum_type
*ct
= NULL
;
1989 if (crypto
!= NULL
) {
1990 ct
= crypto
->et
->keyed_checksum
;
1992 ct
= crypto
->et
->checksum
;
1996 krb5_set_error_string (context
, "checksum type not found");
1997 return KRB5_PROG_SUMTYPE_NOSUPP
;
2006 krb5_error_code KRB5_LIB_FUNCTION
2007 krb5_checksumsize(krb5_context context
,
2008 krb5_cksumtype type
,
2011 struct checksum_type
*ct
= _find_checksum(type
);
2013 krb5_set_error_string (context
, "checksum type %d not supported",
2015 return KRB5_PROG_SUMTYPE_NOSUPP
;
2017 *size
= ct
->checksumsize
;
2021 krb5_boolean KRB5_LIB_FUNCTION
2022 krb5_checksum_is_keyed(krb5_context context
,
2023 krb5_cksumtype type
)
2025 struct checksum_type
*ct
= _find_checksum(type
);
2028 krb5_set_error_string (context
, "checksum type %d not supported",
2030 return KRB5_PROG_SUMTYPE_NOSUPP
;
2032 return ct
->flags
& F_KEYED
;
2035 krb5_boolean KRB5_LIB_FUNCTION
2036 krb5_checksum_is_collision_proof(krb5_context context
,
2037 krb5_cksumtype type
)
2039 struct checksum_type
*ct
= _find_checksum(type
);
2042 krb5_set_error_string (context
, "checksum type %d not supported",
2044 return KRB5_PROG_SUMTYPE_NOSUPP
;
2046 return ct
->flags
& F_CPROOF
;
2049 krb5_error_code KRB5_LIB_FUNCTION
2050 krb5_checksum_disable(krb5_context context
,
2051 krb5_cksumtype type
)
2053 struct checksum_type
*ct
= _find_checksum(type
);
2056 krb5_set_error_string (context
, "checksum type %d not supported",
2058 return KRB5_PROG_SUMTYPE_NOSUPP
;
2060 ct
->flags
|= F_DISABLED
;
2064 /************************************************************
2066 ************************************************************/
2068 static krb5_error_code
2069 NULL_encrypt(krb5_context context
,
2070 struct key_data
*key
,
2073 krb5_boolean encryptp
,
2080 static krb5_error_code
2081 DES_CBC_encrypt_null_ivec(krb5_context context
,
2082 struct key_data
*key
,
2085 krb5_boolean encryptp
,
2090 DES_key_schedule
*s
= key
->schedule
->data
;
2091 memset(&ivec
, 0, sizeof(ivec
));
2092 DES_cbc_encrypt(data
, data
, len
, s
, &ivec
, encryptp
);
2096 static krb5_error_code
2097 DES_CBC_encrypt_key_ivec(krb5_context context
,
2098 struct key_data
*key
,
2101 krb5_boolean encryptp
,
2106 DES_key_schedule
*s
= key
->schedule
->data
;
2107 memcpy(&ivec
, key
->key
->keyvalue
.data
, sizeof(ivec
));
2108 DES_cbc_encrypt(data
, data
, len
, s
, &ivec
, encryptp
);
2112 static krb5_error_code
2113 DES3_CBC_encrypt(krb5_context context
,
2114 struct key_data
*key
,
2117 krb5_boolean encryptp
,
2121 DES_cblock local_ivec
;
2122 DES_key_schedule
*s
= key
->schedule
->data
;
2125 memset(local_ivec
, 0, sizeof(local_ivec
));
2127 DES_ede3_cbc_encrypt(data
, data
, len
, &s
[0], &s
[1], &s
[2], ivec
, encryptp
);
2131 static krb5_error_code
2132 DES_CFB64_encrypt_null_ivec(krb5_context context
,
2133 struct key_data
*key
,
2136 krb5_boolean encryptp
,
2142 DES_key_schedule
*s
= key
->schedule
->data
;
2143 memset(&ivec
, 0, sizeof(ivec
));
2145 DES_cfb64_encrypt(data
, data
, len
, s
, &ivec
, &num
, encryptp
);
2149 static krb5_error_code
2150 DES_PCBC_encrypt_key_ivec(krb5_context context
,
2151 struct key_data
*key
,
2154 krb5_boolean encryptp
,
2159 DES_key_schedule
*s
= key
->schedule
->data
;
2160 memcpy(&ivec
, key
->key
->keyvalue
.data
, sizeof(ivec
));
2162 DES_pcbc_encrypt(data
, data
, len
, s
, &ivec
, encryptp
);
2167 * AES draft-raeburn-krb-rijndael-krb-02
2170 void KRB5_LIB_FUNCTION
2171 _krb5_aes_cts_encrypt(const unsigned char *in
, unsigned char *out
,
2172 size_t len
, const AES_KEY
*key
,
2173 unsigned char *ivec
, const int encryptp
)
2175 unsigned char tmp
[AES_BLOCK_SIZE
];
2179 * In the framework of kerberos, the length can never be shorter
2180 * then at least one blocksize.
2185 while(len
> AES_BLOCK_SIZE
) {
2186 for (i
= 0; i
< AES_BLOCK_SIZE
; i
++)
2187 tmp
[i
] = in
[i
] ^ ivec
[i
];
2188 AES_encrypt(tmp
, out
, key
);
2189 memcpy(ivec
, out
, AES_BLOCK_SIZE
);
2190 len
-= AES_BLOCK_SIZE
;
2191 in
+= AES_BLOCK_SIZE
;
2192 out
+= AES_BLOCK_SIZE
;
2195 for (i
= 0; i
< len
; i
++)
2196 tmp
[i
] = in
[i
] ^ ivec
[i
];
2197 for (; i
< AES_BLOCK_SIZE
; i
++)
2198 tmp
[i
] = 0 ^ ivec
[i
];
2200 AES_encrypt(tmp
, out
- AES_BLOCK_SIZE
, key
);
2202 memcpy(out
, ivec
, len
);
2203 memcpy(ivec
, out
- AES_BLOCK_SIZE
, AES_BLOCK_SIZE
);
2206 unsigned char tmp2
[AES_BLOCK_SIZE
];
2207 unsigned char tmp3
[AES_BLOCK_SIZE
];
2209 while(len
> AES_BLOCK_SIZE
* 2) {
2210 memcpy(tmp
, in
, AES_BLOCK_SIZE
);
2211 AES_decrypt(in
, out
, key
);
2212 for (i
= 0; i
< AES_BLOCK_SIZE
; i
++)
2214 memcpy(ivec
, tmp
, AES_BLOCK_SIZE
);
2215 len
-= AES_BLOCK_SIZE
;
2216 in
+= AES_BLOCK_SIZE
;
2217 out
+= AES_BLOCK_SIZE
;
2220 len
-= AES_BLOCK_SIZE
;
2222 memcpy(tmp
, in
, AES_BLOCK_SIZE
); /* save last iv */
2223 AES_decrypt(in
, tmp2
, key
);
2225 memcpy(tmp3
, in
+ AES_BLOCK_SIZE
, len
);
2226 memcpy(tmp3
+ len
, tmp2
+ len
, AES_BLOCK_SIZE
- len
); /* xor 0 */
2228 for (i
= 0; i
< len
; i
++)
2229 out
[i
+ AES_BLOCK_SIZE
] = tmp2
[i
] ^ tmp3
[i
];
2231 AES_decrypt(tmp3
, out
, key
);
2232 for (i
= 0; i
< AES_BLOCK_SIZE
; i
++)
2234 memcpy(ivec
, tmp
, AES_BLOCK_SIZE
);
2238 static krb5_error_code
2239 AES_CTS_encrypt(krb5_context context
,
2240 struct key_data
*key
,
2243 krb5_boolean encryptp
,
2247 struct krb5_aes_schedule
*aeskey
= key
->schedule
->data
;
2248 char local_ivec
[AES_BLOCK_SIZE
];
2256 if (len
< AES_BLOCK_SIZE
)
2257 krb5_abortx(context
, "invalid use of AES_CTS_encrypt");
2258 if (len
== AES_BLOCK_SIZE
) {
2260 AES_encrypt(data
, data
, k
);
2262 AES_decrypt(data
, data
, k
);
2265 memset(local_ivec
, 0, sizeof(local_ivec
));
2268 _krb5_aes_cts_encrypt(data
, data
, len
, k
, ivec
, encryptp
);
2275 * section 6 of draft-brezak-win2k-krb-rc4-hmac-03
2277 * warning: not for small children
2280 static krb5_error_code
2281 ARCFOUR_subencrypt(krb5_context context
,
2282 struct key_data
*key
,
2288 struct checksum_type
*c
= _find_checksum (CKSUMTYPE_RSA_MD5
);
2289 Checksum k1_c
, k2_c
, k3_c
, cksum
;
2294 unsigned char *cdata
= data
;
2295 unsigned char k1_c_data
[16], k2_c_data
[16], k3_c_data
[16];
2296 krb5_error_code ret
;
2298 t
[0] = (usage
>> 0) & 0xFF;
2299 t
[1] = (usage
>> 8) & 0xFF;
2300 t
[2] = (usage
>> 16) & 0xFF;
2301 t
[3] = (usage
>> 24) & 0xFF;
2303 k1_c
.checksum
.length
= sizeof(k1_c_data
);
2304 k1_c
.checksum
.data
= k1_c_data
;
2306 ret
= hmac(NULL
, c
, t
, sizeof(t
), 0, key
, &k1_c
);
2308 krb5_abortx(context
, "hmac failed");
2310 memcpy (k2_c_data
, k1_c_data
, sizeof(k1_c_data
));
2312 k2_c
.checksum
.length
= sizeof(k2_c_data
);
2313 k2_c
.checksum
.data
= k2_c_data
;
2316 kb
.keyvalue
= k2_c
.checksum
;
2318 cksum
.checksum
.length
= 16;
2319 cksum
.checksum
.data
= data
;
2321 ret
= hmac(NULL
, c
, cdata
+ 16, len
- 16, 0, &ke
, &cksum
);
2323 krb5_abortx(context
, "hmac failed");
2326 kb
.keyvalue
= k1_c
.checksum
;
2328 k3_c
.checksum
.length
= sizeof(k3_c_data
);
2329 k3_c
.checksum
.data
= k3_c_data
;
2331 ret
= hmac(NULL
, c
, data
, 16, 0, &ke
, &k3_c
);
2333 krb5_abortx(context
, "hmac failed");
2335 RC4_set_key (&rc4_key
, k3_c
.checksum
.length
, k3_c
.checksum
.data
);
2336 RC4 (&rc4_key
, len
- 16, cdata
+ 16, cdata
+ 16);
2337 memset (k1_c_data
, 0, sizeof(k1_c_data
));
2338 memset (k2_c_data
, 0, sizeof(k2_c_data
));
2339 memset (k3_c_data
, 0, sizeof(k3_c_data
));
2343 static krb5_error_code
2344 ARCFOUR_subdecrypt(krb5_context context
,
2345 struct key_data
*key
,
2351 struct checksum_type
*c
= _find_checksum (CKSUMTYPE_RSA_MD5
);
2352 Checksum k1_c
, k2_c
, k3_c
, cksum
;
2357 unsigned char *cdata
= data
;
2358 unsigned char k1_c_data
[16], k2_c_data
[16], k3_c_data
[16];
2359 unsigned char cksum_data
[16];
2360 krb5_error_code ret
;
2362 t
[0] = (usage
>> 0) & 0xFF;
2363 t
[1] = (usage
>> 8) & 0xFF;
2364 t
[2] = (usage
>> 16) & 0xFF;
2365 t
[3] = (usage
>> 24) & 0xFF;
2367 k1_c
.checksum
.length
= sizeof(k1_c_data
);
2368 k1_c
.checksum
.data
= k1_c_data
;
2370 ret
= hmac(NULL
, c
, t
, sizeof(t
), 0, key
, &k1_c
);
2372 krb5_abortx(context
, "hmac failed");
2374 memcpy (k2_c_data
, k1_c_data
, sizeof(k1_c_data
));
2376 k2_c
.checksum
.length
= sizeof(k2_c_data
);
2377 k2_c
.checksum
.data
= k2_c_data
;
2380 kb
.keyvalue
= k1_c
.checksum
;
2382 k3_c
.checksum
.length
= sizeof(k3_c_data
);
2383 k3_c
.checksum
.data
= k3_c_data
;
2385 ret
= hmac(NULL
, c
, cdata
, 16, 0, &ke
, &k3_c
);
2387 krb5_abortx(context
, "hmac failed");
2389 RC4_set_key (&rc4_key
, k3_c
.checksum
.length
, k3_c
.checksum
.data
);
2390 RC4 (&rc4_key
, len
- 16, cdata
+ 16, cdata
+ 16);
2393 kb
.keyvalue
= k2_c
.checksum
;
2395 cksum
.checksum
.length
= 16;
2396 cksum
.checksum
.data
= cksum_data
;
2398 ret
= hmac(NULL
, c
, cdata
+ 16, len
- 16, 0, &ke
, &cksum
);
2400 krb5_abortx(context
, "hmac failed");
2402 memset (k1_c_data
, 0, sizeof(k1_c_data
));
2403 memset (k2_c_data
, 0, sizeof(k2_c_data
));
2404 memset (k3_c_data
, 0, sizeof(k3_c_data
));
2406 if (memcmp (cksum
.checksum
.data
, data
, 16) != 0) {
2407 krb5_clear_error_string (context
);
2408 return KRB5KRB_AP_ERR_BAD_INTEGRITY
;
2415 * convert the usage numbers used in
2416 * draft-ietf-cat-kerb-key-derivation-00.txt to the ones in
2417 * draft-brezak-win2k-krb-rc4-hmac-04.txt
2420 static krb5_error_code
2421 usage2arcfour (krb5_context context
, unsigned *usage
)
2424 case KRB5_KU_AS_REP_ENC_PART
: /* 3 */
2425 case KRB5_KU_TGS_REP_ENC_PART_SUB_KEY
: /* 9 */
2428 case KRB5_KU_USAGE_SEAL
: /* 22 */
2431 case KRB5_KU_USAGE_SIGN
: /* 23 */
2434 case KRB5_KU_USAGE_SEQ
: /* 24 */
2442 static krb5_error_code
2443 ARCFOUR_encrypt(krb5_context context
,
2444 struct key_data
*key
,
2447 krb5_boolean encryptp
,
2451 krb5_error_code ret
;
2452 unsigned keyusage
= usage
;
2454 if((ret
= usage2arcfour (context
, &keyusage
)) != 0)
2458 return ARCFOUR_subencrypt (context
, key
, data
, len
, keyusage
, ivec
);
2460 return ARCFOUR_subdecrypt (context
, key
, data
, len
, keyusage
, ivec
);
2468 static krb5_error_code
2469 AES_PRF(krb5_context context
,
2471 const krb5_data
*in
,
2474 struct checksum_type
*ct
= crypto
->et
->checksum
;
2475 krb5_error_code ret
;
2477 krb5_keyblock
*derived
;
2479 result
.cksumtype
= ct
->type
;
2480 ret
= krb5_data_alloc(&result
.checksum
, ct
->checksumsize
);
2482 krb5_set_error_string(context
, "out memory");
2486 (*ct
->checksum
)(context
, NULL
, in
->data
, in
->length
, 0, &result
);
2488 if (result
.checksum
.length
< crypto
->et
->blocksize
)
2489 krb5_abortx(context
, "internal prf error");
2492 ret
= krb5_derive_key(context
, crypto
->key
.key
,
2493 crypto
->et
->type
, "prf", 3, &derived
);
2495 krb5_abortx(context
, "krb5_derive_key");
2497 ret
= krb5_data_alloc(out
, crypto
->et
->blocksize
);
2499 krb5_abortx(context
, "malloc failed");
2504 AES_set_encrypt_key(derived
->keyvalue
.data
,
2505 crypto
->et
->keytype
->bits
, &key
);
2506 AES_encrypt(result
.checksum
.data
, out
->data
, &key
);
2507 memset(&key
, 0, sizeof(key
));
2510 krb5_data_free(&result
.checksum
);
2511 krb5_free_keyblock(context
, derived
);
2517 * these should currently be in reverse preference order.
2518 * (only relevant for !F_PSEUDO) */
2520 static struct encryption_type enctype_null
= {
2535 static struct encryption_type enctype_des_cbc_crc
= {
2546 DES_CBC_encrypt_key_ivec
,
2550 static struct encryption_type enctype_des_cbc_md4
= {
2559 &checksum_rsa_md4_des
,
2561 DES_CBC_encrypt_null_ivec
,
2565 static struct encryption_type enctype_des_cbc_md5
= {
2574 &checksum_rsa_md5_des
,
2576 DES_CBC_encrypt_null_ivec
,
2580 static struct encryption_type enctype_arcfour_hmac_md5
= {
2581 ETYPE_ARCFOUR_HMAC_MD5
,
2595 static struct encryption_type enctype_des3_cbc_md5
= {
2604 &checksum_rsa_md5_des3
,
2610 static struct encryption_type enctype_des3_cbc_sha1
= {
2611 ETYPE_DES3_CBC_SHA1
,
2617 &keytype_des3_derived
,
2619 &checksum_hmac_sha1_des3
,
2625 static struct encryption_type enctype_old_des3_cbc_sha1
= {
2626 ETYPE_OLD_DES3_CBC_SHA1
,
2627 "old-des3-cbc-sha1",
2634 &checksum_hmac_sha1_des3
,
2640 static struct encryption_type enctype_aes128_cts_hmac_sha1
= {
2641 ETYPE_AES128_CTS_HMAC_SHA1_96
,
2642 "aes128-cts-hmac-sha1-96",
2649 &checksum_hmac_sha1_aes128
,
2655 static struct encryption_type enctype_aes256_cts_hmac_sha1
= {
2656 ETYPE_AES256_CTS_HMAC_SHA1_96
,
2657 "aes256-cts-hmac-sha1-96",
2664 &checksum_hmac_sha1_aes256
,
2670 static struct encryption_type enctype_des_cbc_none
= {
2681 DES_CBC_encrypt_null_ivec
,
2685 static struct encryption_type enctype_des_cfb64_none
= {
2686 ETYPE_DES_CFB64_NONE
,
2696 DES_CFB64_encrypt_null_ivec
,
2700 static struct encryption_type enctype_des_pcbc_none
= {
2701 ETYPE_DES_PCBC_NONE
,
2711 DES_PCBC_encrypt_key_ivec
,
2715 static struct encryption_type enctype_des3_cbc_none
= {
2716 ETYPE_DES3_CBC_NONE
,
2722 &keytype_des3_derived
,
2731 static struct encryption_type
*etypes
[] = {
2733 &enctype_des_cbc_crc
,
2734 &enctype_des_cbc_md4
,
2735 &enctype_des_cbc_md5
,
2736 &enctype_arcfour_hmac_md5
,
2737 &enctype_des3_cbc_md5
,
2738 &enctype_des3_cbc_sha1
,
2739 &enctype_old_des3_cbc_sha1
,
2740 &enctype_aes128_cts_hmac_sha1
,
2741 &enctype_aes256_cts_hmac_sha1
,
2742 &enctype_des_cbc_none
,
2743 &enctype_des_cfb64_none
,
2744 &enctype_des_pcbc_none
,
2745 &enctype_des3_cbc_none
2748 static unsigned num_etypes
= sizeof(etypes
) / sizeof(etypes
[0]);
2751 static struct encryption_type
*
2752 _find_enctype(krb5_enctype type
)
2755 for(i
= 0; i
< num_etypes
; i
++)
2756 if(etypes
[i
]->type
== type
)
2762 krb5_error_code KRB5_LIB_FUNCTION
2763 krb5_enctype_to_string(krb5_context context
,
2767 struct encryption_type
*e
;
2768 e
= _find_enctype(etype
);
2770 krb5_set_error_string (context
, "encryption type %d not supported",
2773 return KRB5_PROG_ETYPE_NOSUPP
;
2775 *string
= strdup(e
->name
);
2776 if(*string
== NULL
) {
2777 krb5_set_error_string(context
, "malloc: out of memory");
2783 krb5_error_code KRB5_LIB_FUNCTION
2784 krb5_string_to_enctype(krb5_context context
,
2786 krb5_enctype
*etype
)
2789 for(i
= 0; i
< num_etypes
; i
++)
2790 if(strcasecmp(etypes
[i
]->name
, string
) == 0){
2791 *etype
= etypes
[i
]->type
;
2794 krb5_set_error_string (context
, "encryption type %s not supported",
2796 return KRB5_PROG_ETYPE_NOSUPP
;
2799 krb5_error_code KRB5_LIB_FUNCTION
2800 _krb5_enctype_to_oid(krb5_context context
,
2804 struct encryption_type
*et
= _find_enctype(etype
);
2806 krb5_set_error_string (context
, "encryption type %d not supported",
2808 return KRB5_PROG_ETYPE_NOSUPP
;
2810 if(et
->oid
== NULL
) {
2811 krb5_set_error_string (context
, "%s have not oid", et
->name
);
2812 return KRB5_PROG_ETYPE_NOSUPP
;
2814 krb5_clear_error_string(context
);
2815 return der_copy_oid(et
->oid
, oid
);
2818 krb5_error_code KRB5_LIB_FUNCTION
2819 _krb5_oid_to_enctype(krb5_context context
,
2820 const heim_oid
*oid
,
2821 krb5_enctype
*etype
)
2824 for(i
= 0; i
< num_etypes
; i
++) {
2825 if(etypes
[i
]->oid
&& der_heim_oid_cmp(etypes
[i
]->oid
, oid
) == 0) {
2826 *etype
= etypes
[i
]->type
;
2830 krb5_set_error_string(context
, "enctype for oid not supported");
2831 return KRB5_PROG_ETYPE_NOSUPP
;
2834 krb5_error_code KRB5_LIB_FUNCTION
2835 krb5_enctype_to_keytype(krb5_context context
,
2837 krb5_keytype
*keytype
)
2839 struct encryption_type
*e
= _find_enctype(etype
);
2841 krb5_set_error_string (context
, "encryption type %d not supported",
2843 return KRB5_PROG_ETYPE_NOSUPP
;
2845 *keytype
= e
->keytype
->type
; /* XXX */
2850 krb5_error_code KRB5_LIB_FUNCTION
2851 krb5_keytype_to_enctype(krb5_context context
,
2852 krb5_keytype keytype
,
2853 krb5_enctype
*etype
)
2855 struct key_type
*kt
= _find_keytype(keytype
);
2856 krb5_warnx(context
, "krb5_keytype_to_enctype(%u)", keytype
);
2858 return KRB5_PROG_KEYTYPE_NOSUPP
;
2859 *etype
= kt
->best_etype
;
2864 krb5_error_code KRB5_LIB_FUNCTION
2865 krb5_keytype_to_enctypes (krb5_context context
,
2866 krb5_keytype keytype
,
2874 for (i
= num_etypes
- 1; i
>= 0; --i
) {
2875 if (etypes
[i
]->keytype
->type
== keytype
2876 && !(etypes
[i
]->flags
& F_PSEUDO
))
2879 ret
= malloc(n
* sizeof(*ret
));
2880 if (ret
== NULL
&& n
!= 0) {
2881 krb5_set_error_string(context
, "malloc: out of memory");
2885 for (i
= num_etypes
- 1; i
>= 0; --i
) {
2886 if (etypes
[i
]->keytype
->type
== keytype
2887 && !(etypes
[i
]->flags
& F_PSEUDO
))
2888 ret
[n
++] = etypes
[i
]->type
;
2896 * First take the configured list of etypes for `keytype' if available,
2897 * else, do `krb5_keytype_to_enctypes'.
2900 krb5_error_code KRB5_LIB_FUNCTION
2901 krb5_keytype_to_enctypes_default (krb5_context context
,
2902 krb5_keytype keytype
,
2909 if (keytype
!= KEYTYPE_DES
|| context
->etypes_des
== NULL
)
2910 return krb5_keytype_to_enctypes (context
, keytype
, len
, val
);
2912 for (n
= 0; context
->etypes_des
[n
]; ++n
)
2914 ret
= malloc (n
* sizeof(*ret
));
2915 if (ret
== NULL
&& n
!= 0) {
2916 krb5_set_error_string(context
, "malloc: out of memory");
2919 for (i
= 0; i
< n
; ++i
)
2920 ret
[i
] = context
->etypes_des
[i
];
2926 krb5_error_code KRB5_LIB_FUNCTION
2927 krb5_enctype_valid(krb5_context context
,
2930 struct encryption_type
*e
= _find_enctype(etype
);
2932 krb5_set_error_string (context
, "encryption type %d not supported",
2934 return KRB5_PROG_ETYPE_NOSUPP
;
2936 if (e
->flags
& F_DISABLED
) {
2937 krb5_set_error_string (context
, "encryption type %s is disabled",
2939 return KRB5_PROG_ETYPE_NOSUPP
;
2944 krb5_error_code KRB5_LIB_FUNCTION
2945 krb5_cksumtype_valid(krb5_context context
,
2946 krb5_cksumtype ctype
)
2948 struct checksum_type
*c
= _find_checksum(ctype
);
2950 krb5_set_error_string (context
, "checksum type %d not supported",
2952 return KRB5_PROG_SUMTYPE_NOSUPP
;
2954 if (c
->flags
& F_DISABLED
) {
2955 krb5_set_error_string (context
, "checksum type %s is disabled",
2957 return KRB5_PROG_SUMTYPE_NOSUPP
;
2963 /* if two enctypes have compatible keys */
2964 krb5_boolean KRB5_LIB_FUNCTION
2965 krb5_enctypes_compatible_keys(krb5_context context
,
2966 krb5_enctype etype1
,
2967 krb5_enctype etype2
)
2969 struct encryption_type
*e1
= _find_enctype(etype1
);
2970 struct encryption_type
*e2
= _find_enctype(etype2
);
2971 return e1
!= NULL
&& e2
!= NULL
&& e1
->keytype
== e2
->keytype
;
2975 derived_crypto(krb5_context context
,
2978 return (crypto
->et
->flags
& F_DERIVED
) != 0;
2982 special_crypto(krb5_context context
,
2985 return (crypto
->et
->flags
& F_SPECIAL
) != 0;
2988 #define CHECKSUMSIZE(C) ((C)->checksumsize)
2989 #define CHECKSUMTYPE(C) ((C)->type)
2991 static krb5_error_code
2992 encrypt_internal_derived(krb5_context context
,
3000 size_t sz
, block_sz
, checksum_sz
, total_sz
;
3002 unsigned char *p
, *q
;
3003 krb5_error_code ret
;
3004 struct key_data
*dkey
;
3005 const struct encryption_type
*et
= crypto
->et
;
3007 checksum_sz
= CHECKSUMSIZE(et
->keyed_checksum
);
3009 sz
= et
->confoundersize
+ len
;
3010 block_sz
= (sz
+ et
->padsize
- 1) &~ (et
->padsize
- 1); /* pad */
3011 total_sz
= block_sz
+ checksum_sz
;
3012 p
= calloc(1, total_sz
);
3014 krb5_set_error_string(context
, "malloc: out of memory");
3019 krb5_generate_random_block(q
, et
->confoundersize
); /* XXX */
3020 q
+= et
->confoundersize
;
3021 memcpy(q
, data
, len
);
3023 ret
= create_checksum(context
,
3026 INTEGRITY_USAGE(usage
),
3030 if(ret
== 0 && cksum
.checksum
.length
!= checksum_sz
) {
3031 free_Checksum (&cksum
);
3032 krb5_clear_error_string (context
);
3033 ret
= KRB5_CRYPTO_INTERNAL
;
3037 memcpy(p
+ block_sz
, cksum
.checksum
.data
, cksum
.checksum
.length
);
3038 free_Checksum (&cksum
);
3039 ret
= _get_derived_key(context
, crypto
, ENCRYPTION_USAGE(usage
), &dkey
);
3042 ret
= _key_schedule(context
, dkey
);
3046 krb5_crypto_debug(context
, 1, block_sz
, dkey
->key
);
3048 ret
= (*et
->encrypt
)(context
, dkey
, p
, block_sz
, 1, usage
, ivec
);
3052 result
->length
= total_sz
;
3055 memset(p
, 0, total_sz
);
3061 static krb5_error_code
3062 encrypt_internal(krb5_context context
,
3069 size_t sz
, block_sz
, checksum_sz
;
3071 unsigned char *p
, *q
;
3072 krb5_error_code ret
;
3073 const struct encryption_type
*et
= crypto
->et
;
3075 checksum_sz
= CHECKSUMSIZE(et
->checksum
);
3077 sz
= et
->confoundersize
+ checksum_sz
+ len
;
3078 block_sz
= (sz
+ et
->padsize
- 1) &~ (et
->padsize
- 1); /* pad */
3079 p
= calloc(1, block_sz
);
3081 krb5_set_error_string(context
, "malloc: out of memory");
3086 krb5_generate_random_block(q
, et
->confoundersize
); /* XXX */
3087 q
+= et
->confoundersize
;
3088 memset(q
, 0, checksum_sz
);
3090 memcpy(q
, data
, len
);
3092 ret
= create_checksum(context
,
3099 if(ret
== 0 && cksum
.checksum
.length
!= checksum_sz
) {
3100 krb5_clear_error_string (context
);
3101 free_Checksum(&cksum
);
3102 ret
= KRB5_CRYPTO_INTERNAL
;
3106 memcpy(p
+ et
->confoundersize
, cksum
.checksum
.data
, cksum
.checksum
.length
);
3107 free_Checksum(&cksum
);
3108 ret
= _key_schedule(context
, &crypto
->key
);
3112 krb5_crypto_debug(context
, 1, block_sz
, crypto
->key
.key
);
3114 ret
= (*et
->encrypt
)(context
, &crypto
->key
, p
, block_sz
, 1, 0, ivec
);
3116 memset(p
, 0, block_sz
);
3121 result
->length
= block_sz
;
3124 memset(p
, 0, block_sz
);
3129 static krb5_error_code
3130 encrypt_internal_special(krb5_context context
,
3138 struct encryption_type
*et
= crypto
->et
;
3139 size_t cksum_sz
= CHECKSUMSIZE(et
->checksum
);
3140 size_t sz
= len
+ cksum_sz
+ et
->confoundersize
;
3142 krb5_error_code ret
;
3146 krb5_set_error_string(context
, "malloc: out of memory");
3150 memset (p
, 0, cksum_sz
);
3152 krb5_generate_random_block(p
, et
->confoundersize
);
3153 p
+= et
->confoundersize
;
3154 memcpy (p
, data
, len
);
3155 ret
= (*et
->encrypt
)(context
, &crypto
->key
, tmp
, sz
, TRUE
, usage
, ivec
);
3162 result
->length
= sz
;
3166 static krb5_error_code
3167 decrypt_internal_derived(krb5_context context
,
3178 krb5_error_code ret
;
3179 struct key_data
*dkey
;
3180 struct encryption_type
*et
= crypto
->et
;
3183 checksum_sz
= CHECKSUMSIZE(et
->keyed_checksum
);
3184 if (len
< checksum_sz
+ et
->confoundersize
) {
3185 krb5_set_error_string(context
, "Encrypted data shorter then "
3186 "checksum + confunder");
3187 return KRB5_BAD_MSIZE
;
3190 if (((len
- checksum_sz
) % et
->padsize
) != 0) {
3191 krb5_clear_error_string(context
);
3192 return KRB5_BAD_MSIZE
;
3196 if(len
!= 0 && p
== NULL
) {
3197 krb5_set_error_string(context
, "malloc: out of memory");
3200 memcpy(p
, data
, len
);
3204 ret
= _get_derived_key(context
, crypto
, ENCRYPTION_USAGE(usage
), &dkey
);
3209 ret
= _key_schedule(context
, dkey
);
3215 krb5_crypto_debug(context
, 0, len
, dkey
->key
);
3217 ret
= (*et
->encrypt
)(context
, dkey
, p
, len
, 0, usage
, ivec
);
3223 cksum
.checksum
.data
= p
+ len
;
3224 cksum
.checksum
.length
= checksum_sz
;
3225 cksum
.cksumtype
= CHECKSUMTYPE(et
->keyed_checksum
);
3227 ret
= verify_checksum(context
,
3229 INTEGRITY_USAGE(usage
),
3237 l
= len
- et
->confoundersize
;
3238 memmove(p
, p
+ et
->confoundersize
, l
);
3239 result
->data
= realloc(p
, l
);
3240 if(result
->data
== NULL
&& l
!= 0) {
3242 krb5_set_error_string(context
, "malloc: out of memory");
3249 static krb5_error_code
3250 decrypt_internal(krb5_context context
,
3257 krb5_error_code ret
;
3260 size_t checksum_sz
, l
;
3261 struct encryption_type
*et
= crypto
->et
;
3263 if ((len
% et
->padsize
) != 0) {
3264 krb5_clear_error_string(context
);
3265 return KRB5_BAD_MSIZE
;
3268 checksum_sz
= CHECKSUMSIZE(et
->checksum
);
3270 if(len
!= 0 && p
== NULL
) {
3271 krb5_set_error_string(context
, "malloc: out of memory");
3274 memcpy(p
, data
, len
);
3276 ret
= _key_schedule(context
, &crypto
->key
);
3282 krb5_crypto_debug(context
, 0, len
, crypto
->key
.key
);
3284 ret
= (*et
->encrypt
)(context
, &crypto
->key
, p
, len
, 0, 0, ivec
);
3289 ret
= krb5_data_copy(&cksum
.checksum
, p
+ et
->confoundersize
, checksum_sz
);
3294 memset(p
+ et
->confoundersize
, 0, checksum_sz
);
3295 cksum
.cksumtype
= CHECKSUMTYPE(et
->checksum
);
3296 ret
= verify_checksum(context
, NULL
, 0, p
, len
, &cksum
);
3297 free_Checksum(&cksum
);
3302 l
= len
- et
->confoundersize
- checksum_sz
;
3303 memmove(p
, p
+ et
->confoundersize
+ checksum_sz
, l
);
3304 result
->data
= realloc(p
, l
);
3305 if(result
->data
== NULL
&& l
!= 0) {
3307 krb5_set_error_string(context
, "malloc: out of memory");
3314 static krb5_error_code
3315 decrypt_internal_special(krb5_context context
,
3323 struct encryption_type
*et
= crypto
->et
;
3324 size_t cksum_sz
= CHECKSUMSIZE(et
->checksum
);
3325 size_t sz
= len
- cksum_sz
- et
->confoundersize
;
3327 krb5_error_code ret
;
3329 if ((len
% et
->padsize
) != 0) {
3330 krb5_clear_error_string(context
);
3331 return KRB5_BAD_MSIZE
;
3336 krb5_set_error_string(context
, "malloc: out of memory");
3339 memcpy(p
, data
, len
);
3341 ret
= (*et
->encrypt
)(context
, &crypto
->key
, p
, len
, FALSE
, usage
, ivec
);
3347 memmove (p
, p
+ cksum_sz
+ et
->confoundersize
, sz
);
3348 result
->data
= realloc(p
, sz
);
3349 if(result
->data
== NULL
&& sz
!= 0) {
3351 krb5_set_error_string(context
, "malloc: out of memory");
3354 result
->length
= sz
;
3359 krb5_error_code KRB5_LIB_FUNCTION
3360 krb5_encrypt_ivec(krb5_context context
,
3368 if(derived_crypto(context
, crypto
))
3369 return encrypt_internal_derived(context
, crypto
, usage
,
3370 data
, len
, result
, ivec
);
3371 else if (special_crypto(context
, crypto
))
3372 return encrypt_internal_special (context
, crypto
, usage
,
3373 data
, len
, result
, ivec
);
3375 return encrypt_internal(context
, crypto
, data
, len
, result
, ivec
);
3378 krb5_error_code KRB5_LIB_FUNCTION
3379 krb5_encrypt(krb5_context context
,
3386 return krb5_encrypt_ivec(context
, crypto
, usage
, data
, len
, result
, NULL
);
3389 krb5_error_code KRB5_LIB_FUNCTION
3390 krb5_encrypt_EncryptedData(krb5_context context
,
3396 EncryptedData
*result
)
3398 result
->etype
= CRYPTO_ETYPE(crypto
);
3400 ALLOC(result
->kvno
, 1);
3401 *result
->kvno
= kvno
;
3403 result
->kvno
= NULL
;
3404 return krb5_encrypt(context
, crypto
, usage
, data
, len
, &result
->cipher
);
3407 krb5_error_code KRB5_LIB_FUNCTION
3408 krb5_decrypt_ivec(krb5_context context
,
3416 if(derived_crypto(context
, crypto
))
3417 return decrypt_internal_derived(context
, crypto
, usage
,
3418 data
, len
, result
, ivec
);
3419 else if (special_crypto (context
, crypto
))
3420 return decrypt_internal_special(context
, crypto
, usage
,
3421 data
, len
, result
, ivec
);
3423 return decrypt_internal(context
, crypto
, data
, len
, result
, ivec
);
3426 krb5_error_code KRB5_LIB_FUNCTION
3427 krb5_decrypt(krb5_context context
,
3434 return krb5_decrypt_ivec (context
, crypto
, usage
, data
, len
, result
,
3438 krb5_error_code KRB5_LIB_FUNCTION
3439 krb5_decrypt_EncryptedData(krb5_context context
,
3442 const EncryptedData
*e
,
3445 return krb5_decrypt(context
, crypto
, usage
,
3446 e
->cipher
.data
, e
->cipher
.length
, result
);
3449 /************************************************************
3451 ************************************************************/
3453 #define ENTROPY_NEEDED 128
3456 seed_something(void)
3458 char buf
[1024], seedfile
[256];
3460 /* If there is a seed file, load it. But such a file cannot be trusted,
3461 so use 0 for the entropy estimate */
3462 if (RAND_file_name(seedfile
, sizeof(seedfile
))) {
3464 fd
= open(seedfile
, O_RDONLY
);
3467 ret
= read(fd
, buf
, sizeof(buf
));
3469 RAND_add(buf
, ret
, 0.0);
3476 /* Calling RAND_status() will try to use /dev/urandom if it exists so
3477 we do not have to deal with it. */
3478 if (RAND_status() != 1) {
3479 krb5_context context
;
3483 if (!krb5_init_context(&context
)) {
3484 p
= krb5_config_get_string(context
, NULL
, "libdefaults",
3485 "egd_socket", NULL
);
3487 RAND_egd_bytes(p
, ENTROPY_NEEDED
);
3488 krb5_free_context(context
);
3492 if (RAND_status() == 1) {
3493 /* Update the seed file */
3495 RAND_write_file(seedfile
);
3502 void KRB5_LIB_FUNCTION
3503 krb5_generate_random_block(void *buf
, size_t len
)
3505 static int rng_initialized
= 0;
3507 HEIMDAL_MUTEX_lock(&crypto_mutex
);
3508 if (!rng_initialized
) {
3509 if (seed_something())
3510 krb5_abortx(NULL
, "Fatal: could not seed the "
3511 "random number generator");
3513 rng_initialized
= 1;
3515 HEIMDAL_MUTEX_unlock(&crypto_mutex
);
3516 if (RAND_bytes(buf
, len
) != 1)
3517 krb5_abortx(NULL
, "Failed to generate random block");
3521 DES3_postproc(krb5_context context
,
3522 unsigned char *k
, size_t len
, struct key_data
*key
)
3524 DES3_random_to_key(context
, key
->key
, k
, len
);
3526 if (key
->schedule
) {
3527 krb5_free_data(context
, key
->schedule
);
3528 key
->schedule
= NULL
;
3532 static krb5_error_code
3533 derive_key(krb5_context context
,
3534 struct encryption_type
*et
,
3535 struct key_data
*key
,
3536 const void *constant
,
3540 unsigned int nblocks
= 0, i
;
3541 krb5_error_code ret
= 0;
3542 struct key_type
*kt
= et
->keytype
;
3544 ret
= _key_schedule(context
, key
);
3547 if(et
->blocksize
* 8 < kt
->bits
|| len
!= et
->blocksize
) {
3548 nblocks
= (kt
->bits
+ et
->blocksize
* 8 - 1) / (et
->blocksize
* 8);
3549 k
= malloc(nblocks
* et
->blocksize
);
3551 krb5_set_error_string(context
, "malloc: out of memory");
3554 ret
= _krb5_n_fold(constant
, len
, k
, et
->blocksize
);
3557 krb5_set_error_string(context
, "out of memory");
3560 for(i
= 0; i
< nblocks
; i
++) {
3562 memcpy(k
+ i
* et
->blocksize
,
3563 k
+ (i
- 1) * et
->blocksize
,
3565 (*et
->encrypt
)(context
, key
, k
+ i
* et
->blocksize
, et
->blocksize
,
3569 /* this case is probably broken, but won't be run anyway */
3570 void *c
= malloc(len
);
3571 size_t res_len
= (kt
->bits
+ 7) / 8;
3573 if(len
!= 0 && c
== NULL
) {
3574 krb5_set_error_string(context
, "malloc: out of memory");
3577 memcpy(c
, constant
, len
);
3578 (*et
->encrypt
)(context
, key
, c
, len
, 1, 0, NULL
);
3579 k
= malloc(res_len
);
3580 if(res_len
!= 0 && k
== NULL
) {
3582 krb5_set_error_string(context
, "malloc: out of memory");
3585 ret
= _krb5_n_fold(c
, len
, k
, res_len
);
3588 krb5_set_error_string(context
, "out of memory");
3594 /* XXX keytype dependent post-processing */
3597 DES3_postproc(context
, k
, nblocks
* et
->blocksize
, key
);
3599 case KEYTYPE_AES128
:
3600 case KEYTYPE_AES256
:
3601 memcpy(key
->key
->keyvalue
.data
, k
, key
->key
->keyvalue
.length
);
3604 krb5_set_error_string(context
,
3605 "derive_key() called with unknown keytype (%u)",
3607 ret
= KRB5_CRYPTO_INTERNAL
;
3610 if (key
->schedule
) {
3611 krb5_free_data(context
, key
->schedule
);
3612 key
->schedule
= NULL
;
3614 memset(k
, 0, nblocks
* et
->blocksize
);
3619 static struct key_data
*
3620 _new_derived_key(krb5_crypto crypto
, unsigned usage
)
3622 struct key_usage
*d
= crypto
->key_usage
;
3623 d
= realloc(d
, (crypto
->num_key_usage
+ 1) * sizeof(*d
));
3626 crypto
->key_usage
= d
;
3627 d
+= crypto
->num_key_usage
++;
3628 memset(d
, 0, sizeof(*d
));
3633 krb5_error_code KRB5_LIB_FUNCTION
3634 krb5_derive_key(krb5_context context
,
3635 const krb5_keyblock
*key
,
3637 const void *constant
,
3638 size_t constant_len
,
3639 krb5_keyblock
**derived_key
)
3641 krb5_error_code ret
;
3642 struct encryption_type
*et
;
3645 *derived_key
= NULL
;
3647 et
= _find_enctype (etype
);
3649 krb5_set_error_string(context
, "encryption type %d not supported",
3651 return KRB5_PROG_ETYPE_NOSUPP
;
3654 ret
= krb5_copy_keyblock(context
, key
, &d
.key
);
3659 ret
= derive_key(context
, et
, &d
, constant
, constant_len
);
3661 ret
= krb5_copy_keyblock(context
, d
.key
, derived_key
);
3662 free_key_data(context
, &d
);
3666 static krb5_error_code
3667 _get_derived_key(krb5_context context
,
3670 struct key_data
**key
)
3674 unsigned char constant
[5];
3676 for(i
= 0; i
< crypto
->num_key_usage
; i
++)
3677 if(crypto
->key_usage
[i
].usage
== usage
) {
3678 *key
= &crypto
->key_usage
[i
].key
;
3681 d
= _new_derived_key(crypto
, usage
);
3683 krb5_set_error_string(context
, "malloc: out of memory");
3686 krb5_copy_keyblock(context
, crypto
->key
.key
, &d
->key
);
3687 _krb5_put_int(constant
, usage
, 5);
3688 derive_key(context
, crypto
->et
, d
, constant
, sizeof(constant
));
3694 krb5_error_code KRB5_LIB_FUNCTION
3695 krb5_crypto_init(krb5_context context
,
3696 const krb5_keyblock
*key
,
3698 krb5_crypto
*crypto
)
3700 krb5_error_code ret
;
3702 if(*crypto
== NULL
) {
3703 krb5_set_error_string(context
, "malloc: out of memory");
3706 if(etype
== ETYPE_NULL
)
3707 etype
= key
->keytype
;
3708 (*crypto
)->et
= _find_enctype(etype
);
3709 if((*crypto
)->et
== NULL
|| ((*crypto
)->et
->flags
& F_DISABLED
)) {
3712 krb5_set_error_string (context
, "encryption type %d not supported",
3714 return KRB5_PROG_ETYPE_NOSUPP
;
3716 if((*crypto
)->et
->keytype
->size
!= key
->keyvalue
.length
) {
3719 krb5_set_error_string (context
, "encryption key has bad length");
3720 return KRB5_BAD_KEYSIZE
;
3722 ret
= krb5_copy_keyblock(context
, key
, &(*crypto
)->key
.key
);
3728 (*crypto
)->key
.schedule
= NULL
;
3729 (*crypto
)->num_key_usage
= 0;
3730 (*crypto
)->key_usage
= NULL
;
3735 free_key_data(krb5_context context
, struct key_data
*key
)
3737 krb5_free_keyblock(context
, key
->key
);
3739 memset(key
->schedule
->data
, 0, key
->schedule
->length
);
3740 krb5_free_data(context
, key
->schedule
);
3745 free_key_usage(krb5_context context
, struct key_usage
*ku
)
3747 free_key_data(context
, &ku
->key
);
3750 krb5_error_code KRB5_LIB_FUNCTION
3751 krb5_crypto_destroy(krb5_context context
,
3756 for(i
= 0; i
< crypto
->num_key_usage
; i
++)
3757 free_key_usage(context
, &crypto
->key_usage
[i
]);
3758 free(crypto
->key_usage
);
3759 free_key_data(context
, &crypto
->key
);
3764 krb5_error_code KRB5_LIB_FUNCTION
3765 krb5_crypto_getblocksize(krb5_context context
,
3769 *blocksize
= crypto
->et
->blocksize
;
3773 krb5_error_code KRB5_LIB_FUNCTION
3774 krb5_crypto_getenctype(krb5_context context
,
3776 krb5_enctype
*enctype
)
3778 *enctype
= crypto
->et
->type
;
3782 krb5_error_code KRB5_LIB_FUNCTION
3783 krb5_crypto_getpadsize(krb5_context context
,
3787 *padsize
= crypto
->et
->padsize
;
3791 krb5_error_code KRB5_LIB_FUNCTION
3792 krb5_crypto_getconfoundersize(krb5_context context
,
3794 size_t *confoundersize
)
3796 *confoundersize
= crypto
->et
->confoundersize
;
3800 krb5_error_code KRB5_LIB_FUNCTION
3801 krb5_enctype_disable(krb5_context context
,
3802 krb5_enctype enctype
)
3804 struct encryption_type
*et
= _find_enctype(enctype
);
3807 krb5_set_error_string (context
, "encryption type %d not supported",
3809 return KRB5_PROG_ETYPE_NOSUPP
;
3811 et
->flags
|= F_DISABLED
;
3815 krb5_error_code KRB5_LIB_FUNCTION
3816 krb5_string_to_key_derived(krb5_context context
,
3822 struct encryption_type
*et
= _find_enctype(etype
);
3823 krb5_error_code ret
;
3829 krb5_set_error_string (context
, "encryption type %d not supported",
3831 return KRB5_PROG_ETYPE_NOSUPP
;
3833 keylen
= et
->keytype
->bits
/ 8;
3836 if(kd
.key
== NULL
) {
3837 krb5_set_error_string (context
, "malloc: out of memory");
3840 ret
= krb5_data_alloc(&kd
.key
->keyvalue
, et
->keytype
->size
);
3845 kd
.key
->keytype
= etype
;
3846 tmp
= malloc (keylen
);
3848 krb5_free_keyblock(context
, kd
.key
);
3849 krb5_set_error_string (context
, "malloc: out of memory");
3852 ret
= _krb5_n_fold(str
, len
, tmp
, keylen
);
3855 krb5_set_error_string(context
, "out of memory");
3859 DES3_postproc (context
, tmp
, keylen
, &kd
); /* XXX */
3860 memset(tmp
, 0, keylen
);
3862 ret
= derive_key(context
,
3865 "kerberos", /* XXX well known constant */
3866 strlen("kerberos"));
3867 ret
= krb5_copy_keyblock_contents(context
, kd
.key
, key
);
3868 free_key_data(context
, &kd
);
3873 wrapped_length (krb5_context context
,
3877 struct encryption_type
*et
= crypto
->et
;
3878 size_t padsize
= et
->padsize
;
3879 size_t checksumsize
= CHECKSUMSIZE(et
->checksum
);
3882 res
= et
->confoundersize
+ checksumsize
+ data_len
;
3883 res
= (res
+ padsize
- 1) / padsize
* padsize
;
3888 wrapped_length_dervied (krb5_context context
,
3892 struct encryption_type
*et
= crypto
->et
;
3893 size_t padsize
= et
->padsize
;
3896 res
= et
->confoundersize
+ data_len
;
3897 res
= (res
+ padsize
- 1) / padsize
* padsize
;
3898 if (et
->keyed_checksum
)
3899 res
+= et
->keyed_checksum
->checksumsize
;
3901 res
+= et
->checksum
->checksumsize
;
3906 * Return the size of an encrypted packet of length `data_len'
3910 krb5_get_wrapped_length (krb5_context context
,
3914 if (derived_crypto (context
, crypto
))
3915 return wrapped_length_dervied (context
, crypto
, data_len
);
3917 return wrapped_length (context
, crypto
, data_len
);
3921 * Return the size of an encrypted packet of length `data_len'
3925 crypto_overhead (krb5_context context
,
3928 struct encryption_type
*et
= crypto
->et
;
3931 res
= CHECKSUMSIZE(et
->checksum
);
3932 res
+= et
->confoundersize
;
3933 if (et
->padsize
> 1)
3939 crypto_overhead_dervied (krb5_context context
,
3942 struct encryption_type
*et
= crypto
->et
;
3945 if (et
->keyed_checksum
)
3946 res
= CHECKSUMSIZE(et
->keyed_checksum
);
3948 res
= CHECKSUMSIZE(et
->checksum
);
3949 res
+= et
->confoundersize
;
3950 if (et
->padsize
> 1)
3956 krb5_crypto_overhead (krb5_context context
, krb5_crypto crypto
)
3958 if (derived_crypto (context
, crypto
))
3959 return crypto_overhead_dervied (context
, crypto
);
3961 return crypto_overhead (context
, crypto
);
3964 krb5_error_code KRB5_LIB_FUNCTION
3965 krb5_random_to_key(krb5_context context
,
3971 krb5_error_code ret
;
3972 struct encryption_type
*et
= _find_enctype(type
);
3974 krb5_set_error_string(context
, "encryption type %d not supported",
3976 return KRB5_PROG_ETYPE_NOSUPP
;
3978 if ((et
->keytype
->bits
+ 7) / 8 > size
) {
3979 krb5_set_error_string(context
, "encryption key %s needs %d bytes "
3980 "of random to make an encryption key out of it",
3981 et
->name
, (int)et
->keytype
->size
);
3982 return KRB5_PROG_ETYPE_NOSUPP
;
3984 ret
= krb5_data_alloc(&key
->keyvalue
, et
->keytype
->size
);
3987 key
->keytype
= type
;
3988 if (et
->keytype
->random_to_key
)
3989 (*et
->keytype
->random_to_key
)(context
, key
, data
, size
);
3991 memcpy(key
->keyvalue
.data
, data
, et
->keytype
->size
);
3997 _krb5_pk_octetstring2key(krb5_context context
,
4001 const heim_octet_string
*c_n
,
4002 const heim_octet_string
*k_n
,
4005 struct encryption_type
*et
= _find_enctype(type
);
4006 krb5_error_code ret
;
4007 size_t keylen
, offset
;
4009 unsigned char counter
;
4010 unsigned char shaoutput
[20];
4013 krb5_set_error_string(context
, "encryption type %d not supported",
4015 return KRB5_PROG_ETYPE_NOSUPP
;
4017 keylen
= (et
->keytype
->bits
+ 7) / 8;
4019 keydata
= malloc(keylen
);
4020 if (keydata
== NULL
) {
4021 krb5_set_error_string(context
, "malloc: out of memory");
4031 SHA1_Update(&m
, &counter
, 1);
4032 SHA1_Update(&m
, dhdata
, dhsize
);
4034 SHA1_Update(&m
, c_n
->data
, c_n
->length
);
4036 SHA1_Update(&m
, k_n
->data
, k_n
->length
);
4037 SHA1_Final(shaoutput
, &m
);
4039 memcpy((unsigned char *)keydata
+ offset
,
4041 min(keylen
- offset
, sizeof(shaoutput
)));
4043 offset
+= sizeof(shaoutput
);
4045 } while(offset
< keylen
);
4046 memset(shaoutput
, 0, sizeof(shaoutput
));
4048 ret
= krb5_random_to_key(context
, type
, keydata
, keylen
, key
);
4049 memset(keydata
, 0, sizeof(keylen
));
4054 static krb5_error_code
4055 encode_uvinfo(krb5_context context
, krb5_const_principal p
, krb5_data
*data
)
4057 KRB5PrincipalName pn
;
4058 krb5_error_code ret
;
4061 pn
.principalName
= p
->name
;
4062 pn
.realm
= p
->realm
;
4064 ASN1_MALLOC_ENCODE(KRB5PrincipalName
, data
->data
, data
->length
,
4067 krb5_data_zero(data
);
4068 krb5_set_error_string(context
, "Failed to encode KRB5PrincipalName");
4071 if (data
->length
!= size
)
4072 krb5_abortx(context
, "asn1 compiler internal error");
4076 static krb5_error_code
4077 encode_otherinfo(krb5_context context
,
4078 const AlgorithmIdentifier
*ai
,
4079 krb5_const_principal client
,
4080 krb5_const_principal server
,
4081 krb5_enctype enctype
,
4082 const krb5_data
*as_req
,
4083 const krb5_data
*pk_as_rep
,
4084 const Ticket
*ticket
,
4087 PkinitSP80056AOtherInfo otherinfo
;
4088 PkinitSuppPubInfo pubinfo
;
4089 krb5_error_code ret
;
4093 krb5_data_zero(other
);
4094 memset(&otherinfo
, 0, sizeof(otherinfo
));
4095 memset(&pubinfo
, 0, sizeof(pubinfo
));
4097 pubinfo
.enctype
= enctype
;
4098 pubinfo
.as_REQ
= *as_req
;
4099 pubinfo
.pk_as_rep
= *pk_as_rep
;
4100 pubinfo
.ticket
= *ticket
;
4101 ASN1_MALLOC_ENCODE(PkinitSuppPubInfo
, pub
.data
, pub
.length
,
4102 &pubinfo
, &size
, ret
);
4104 krb5_set_error_string(context
, "out of memory");
4107 if (pub
.length
!= size
)
4108 krb5_abortx(context
, "asn1 compiler internal error");
4110 ret
= encode_uvinfo(context
, client
, &otherinfo
.partyUInfo
);
4115 ret
= encode_uvinfo(context
, server
, &otherinfo
.partyVInfo
);
4117 free(otherinfo
.partyUInfo
.data
);
4122 otherinfo
.algorithmID
= *ai
;
4123 otherinfo
.suppPubInfo
= &pub
;
4125 ASN1_MALLOC_ENCODE(PkinitSP80056AOtherInfo
, other
->data
, other
->length
,
4126 &otherinfo
, &size
, ret
);
4127 free(otherinfo
.partyUInfo
.data
);
4128 free(otherinfo
.partyVInfo
.data
);
4131 krb5_set_error_string(context
, "out of memory");
4134 if (other
->length
!= size
)
4135 krb5_abortx(context
, "asn1 compiler internal error");
4141 _krb5_pk_kdf(krb5_context context
,
4142 const struct AlgorithmIdentifier
*ai
,
4145 krb5_const_principal client
,
4146 krb5_const_principal server
,
4147 krb5_enctype enctype
,
4148 const krb5_data
*as_req
,
4149 const krb5_data
*pk_as_rep
,
4150 const Ticket
*ticket
,
4153 struct encryption_type
*et
;
4154 krb5_error_code ret
;
4156 size_t keylen
, offset
;
4158 unsigned char *keydata
;
4159 unsigned char shaoutput
[20];
4161 if (der_heim_oid_cmp(oid_id_pkinit_kdf_ah_sha1(), &ai
->algorithm
) != 0) {
4162 krb5_set_error_string(context
, "kdf not supported");
4163 return KRB5_PROG_ETYPE_NOSUPP
;
4165 if (ai
->parameters
!= NULL
&&
4166 (ai
->parameters
->length
!= 2 ||
4167 memcmp(ai
->parameters
->data
, "\x05\x00", 2) != 0))
4169 krb5_set_error_string(context
, "kdf params not NULL or the NULL-type");
4170 return KRB5_PROG_ETYPE_NOSUPP
;
4173 et
= _find_enctype(enctype
);
4175 krb5_set_error_string(context
, "encryption type %d not supported",
4177 return KRB5_PROG_ETYPE_NOSUPP
;
4179 keylen
= (et
->keytype
->bits
+ 7) / 8;
4181 keydata
= malloc(keylen
);
4182 if (keydata
== NULL
) {
4183 krb5_set_error_string(context
, "malloc: out of memory");
4187 ret
= encode_otherinfo(context
, ai
, client
, server
,
4188 enctype
, as_req
, pk_as_rep
, ticket
, &other
);
4197 unsigned char cdata
[4];
4201 _krb5_put_int(cdata
, counter
, 4);
4202 SHA1_Update(&m
, cdata
, 4);
4203 SHA1_Update(&m
, dhdata
, dhsize
);
4204 SHA1_Update(&m
, other
.data
, other
.length
);
4205 SHA1_Final(shaoutput
, &m
);
4207 memcpy((unsigned char *)keydata
+ offset
,
4209 min(keylen
- offset
, sizeof(shaoutput
)));
4211 offset
+= sizeof(shaoutput
);
4213 } while(offset
< keylen
);
4214 memset(shaoutput
, 0, sizeof(shaoutput
));
4218 ret
= krb5_random_to_key(context
, enctype
, keydata
, keylen
, key
);
4219 memset(keydata
, 0, sizeof(keylen
));
4226 krb5_error_code KRB5_LIB_FUNCTION
4227 krb5_crypto_prf_length(krb5_context context
,
4231 struct encryption_type
*et
= _find_enctype(type
);
4233 if(et
== NULL
|| et
->prf_length
== 0) {
4234 krb5_set_error_string(context
, "encryption type %d not supported",
4236 return KRB5_PROG_ETYPE_NOSUPP
;
4239 *length
= et
->prf_length
;
4243 krb5_error_code KRB5_LIB_FUNCTION
4244 krb5_crypto_prf(krb5_context context
,
4245 const krb5_crypto crypto
,
4246 const krb5_data
*input
,
4249 struct encryption_type
*et
= crypto
->et
;
4251 krb5_data_zero(output
);
4253 if(et
->prf
== NULL
) {
4254 krb5_set_error_string(context
, "kerberos prf for %s not supported",
4256 return KRB5_PROG_ETYPE_NOSUPP
;
4259 return (*et
->prf
)(context
, crypto
, input
, output
);
4267 static krb5_error_code
4268 krb5_get_keyid(krb5_context context
,
4273 unsigned char tmp
[16];
4276 MD5_Update (&md5
, key
->keyvalue
.data
, key
->keyvalue
.length
);
4277 MD5_Final (tmp
, &md5
);
4278 *keyid
= (tmp
[12] << 24) | (tmp
[13] << 16) | (tmp
[14] << 8) | tmp
[15];
4283 krb5_crypto_debug(krb5_context context
,
4290 krb5_get_keyid(context
, key
, &keyid
);
4291 krb5_enctype_to_string(context
, key
->keytype
, &kt
);
4292 krb5_warnx(context
, "%s %lu bytes with key-id %#x (%s)",
4293 encryptp
? "encrypting" : "decrypting",
4300 #endif /* CRYPTO_DEBUG */
4308 krb5_context context
;
4313 unsigned usage
= ENCRYPTION_USAGE(3);
4314 krb5_error_code ret
;
4316 ret
= krb5_init_context(&context
);
4318 errx (1, "krb5_init_context failed: %d", ret
);
4320 key
.keytype
= ETYPE_NEW_DES3_CBC_SHA1
;
4321 key
.keyvalue
.data
= "\xb3\x85\x58\x94\xd9\xdc\x7c\xc8"
4322 "\x25\xe9\x85\xab\x3e\xb5\xfb\x0e"
4323 "\xc8\xdf\xab\x26\x86\x64\x15\x25";
4324 key
.keyvalue
.length
= 24;
4326 krb5_crypto_init(context
, &key
, 0, &crypto
);
4328 d
= _new_derived_key(crypto
, usage
);
4330 krb5_errx(context
, 1, "_new_derived_key failed");
4331 krb5_copy_keyblock(context
, crypto
->key
.key
, &d
->key
);
4332 _krb5_put_int(constant
, usage
, 4);
4333 derive_key(context
, crypto
->et
, d
, constant
, sizeof(constant
));
4337 krb5_context context
;
4341 krb5_error_code ret
;
4344 char *data
= "what do ya want for nothing?";
4346 ret
= krb5_init_context(&context
);
4348 errx (1, "krb5_init_context failed: %d", ret
);
4350 key
.keytype
= ETYPE_NEW_DES3_CBC_SHA1
;
4351 key
.keyvalue
.data
= "Jefe";
4352 /* "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
4353 "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"; */
4354 key
.keyvalue
.length
= 4;
4356 d
= ecalloc(1, sizeof(*d
));
4358 res
.checksum
.length
= 20;
4359 res
.checksum
.data
= emalloc(res
.checksum
.length
);
4360 SP_HMAC_SHA1_checksum(context
, d
, data
, 28, &res
);