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("$Id: crypto.c,v 1.128 2005/07/20 07:22:43 lha Exp $");
39 static void krb5_crypto_debug(krb5_context
, int, size_t, krb5_keyblock
*);
53 struct krb5_crypto_data
{
54 struct encryption_type
*et
;
57 struct key_usage
*key_usage
;
61 #define kcrypto_oid_enc(n) { sizeof(n)/sizeof(n[0]), n }
63 #define CRYPTO_ETYPE(C) ((C)->et->type)
65 /* bits for `flags' below */
66 #define F_KEYED 1 /* checksum is keyed */
67 #define F_CPROOF 2 /* checksum is collision proof */
68 #define F_DERIVED 4 /* uses derived keys */
69 #define F_VARIANT 8 /* uses `variant' keys (6.4.3) */
70 #define F_PSEUDO 16 /* not a real protocol type */
71 #define F_SPECIAL 32 /* backwards */
72 #define F_DISABLED 64 /* enctype/checksum disabled */
73 #define F_PADCMS 128 /* padding done like in CMS */
78 krb5_error_code (*string_to_key
)(krb5_context
, krb5_enctype
, krb5_data
,
79 krb5_salt
, krb5_data
, krb5_keyblock
*);
83 krb5_keytype type
; /* XXX */
90 krb5_enctype best_etype
;
92 void (*random_key
)(krb5_context
, krb5_keyblock
*);
93 void (*schedule
)(krb5_context
, struct key_data
*, const void *);
94 struct salt_type
*string_to_key
;
95 void (*random_to_key
)(krb5_context
, krb5_keyblock
*, const void*, size_t);
96 krb5_error_code (*get_params
)(krb5_context
, const krb5_data
*,
97 void **, krb5_data
*);
98 krb5_error_code (*set_params
)(krb5_context
, const void *,
99 const krb5_data
*, krb5_data
*);
102 struct checksum_type
{
108 void (*checksum
)(krb5_context context
,
109 struct key_data
*key
,
110 const void *buf
, size_t len
,
113 krb5_error_code (*verify
)(krb5_context context
,
114 struct key_data
*key
,
115 const void *buf
, size_t len
,
120 struct encryption_type
{
126 size_t confoundersize
;
127 struct key_type
*keytype
;
128 struct checksum_type
*checksum
;
129 struct checksum_type
*keyed_checksum
;
131 krb5_error_code (*encrypt
)(krb5_context context
,
132 struct key_data
*key
,
133 void *data
, size_t len
,
134 krb5_boolean encryptp
,
139 #define ENCRYPTION_USAGE(U) (((U) << 8) | 0xAA)
140 #define INTEGRITY_USAGE(U) (((U) << 8) | 0x55)
141 #define CHECKSUM_USAGE(U) (((U) << 8) | 0x99)
143 static struct checksum_type
*_find_checksum(krb5_cksumtype type
);
144 static struct encryption_type
*_find_enctype(krb5_enctype type
);
145 static struct key_type
*_find_keytype(krb5_keytype type
);
146 static krb5_error_code
_get_derived_key(krb5_context
, krb5_crypto
,
147 unsigned, struct key_data
**);
148 static struct key_data
*_new_derived_key(krb5_crypto crypto
, unsigned usage
);
149 static krb5_error_code
derive_key(krb5_context context
,
150 struct encryption_type
*et
,
151 struct key_data
*key
,
152 const void *constant
,
154 static krb5_error_code
hmac(krb5_context context
,
155 struct checksum_type
*cm
,
159 struct key_data
*keyblock
,
161 static void free_key_data(krb5_context context
, struct key_data
*key
);
162 static krb5_error_code
usage2arcfour (krb5_context
, unsigned *);
163 static void xor (DES_cblock
*, const unsigned char *);
165 /************************************************************
167 ************************************************************/
169 static HEIMDAL_MUTEX crypto_mutex
= HEIMDAL_MUTEX_INITIALIZER
;
173 krb5_DES_random_key(krb5_context context
,
176 DES_cblock
*k
= key
->keyvalue
.data
;
178 krb5_generate_random_block(k
, sizeof(DES_cblock
));
179 DES_set_odd_parity(k
);
180 } while(DES_is_weak_key(k
));
184 krb5_DES_schedule(krb5_context context
,
185 struct key_data
*key
,
188 DES_set_key(key
->key
->keyvalue
.data
, key
->schedule
->data
);
192 DES_string_to_key_int(unsigned char *data
, size_t length
, DES_cblock
*key
)
194 DES_key_schedule schedule
;
199 unsigned char swap
[] = { 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
200 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf };
203 p
= (unsigned char*)key
;
204 for (i
= 0; i
< length
; i
++) {
205 unsigned char tmp
= data
[i
];
209 *--p
^= (swap
[tmp
& 0xf] << 4) | swap
[(tmp
& 0xf0) >> 4];
213 DES_set_odd_parity(key
);
214 if(DES_is_weak_key(key
))
216 DES_set_key(key
, &schedule
);
217 DES_cbc_cksum((void*)data
, key
, length
, &schedule
, key
);
218 memset(&schedule
, 0, sizeof(schedule
));
219 DES_set_odd_parity(key
);
220 if(DES_is_weak_key(key
))
224 static krb5_error_code
225 krb5_DES_string_to_key(krb5_context context
,
226 krb5_enctype enctype
,
236 len
= password
.length
+ salt
.saltvalue
.length
;
238 if(len
> 0 && s
== NULL
) {
239 krb5_set_error_string(context
, "malloc: out of memory");
242 memcpy(s
, password
.data
, password
.length
);
243 memcpy(s
+ password
.length
, salt
.saltvalue
.data
, salt
.saltvalue
.length
);
244 DES_string_to_key_int(s
, len
, &tmp
);
245 key
->keytype
= enctype
;
246 krb5_data_copy(&key
->keyvalue
, tmp
, sizeof(tmp
));
247 memset(&tmp
, 0, sizeof(tmp
));
253 #ifdef ENABLE_AFS_STRING_TO_KEY
255 /* This defines the Andrew string_to_key function. It accepts a password
256 * string as input and converts its via a one-way encryption algorithm to a DES
257 * encryption key. It is compatible with the original Andrew authentication
258 * service password database.
262 * Short passwords, i.e 8 characters or less.
265 krb5_DES_AFS3_CMU_string_to_key (krb5_data pw
,
269 char password
[8+1]; /* crypt is limited to 8 chars anyway */
272 for(i
= 0; i
< 8; i
++) {
273 char c
= ((i
< pw
.length
) ? ((char*)pw
.data
)[i
] : 0) ^
275 tolower(((unsigned char*)cell
.data
)[i
]) : 0);
276 password
[i
] = c
? c
: 'X';
280 memcpy(key
, crypt(password
, "p1") + 2, sizeof(DES_cblock
));
282 /* parity is inserted into the LSB so left shift each byte up one
283 bit. This allows ascii characters with a zero MSB to retain as
284 much significance as possible. */
285 for (i
= 0; i
< sizeof(DES_cblock
); i
++)
286 ((unsigned char*)key
)[i
] <<= 1;
287 DES_set_odd_parity (key
);
291 * Long passwords, i.e 9 characters or more.
294 krb5_DES_AFS3_Transarc_string_to_key (krb5_data pw
,
298 DES_key_schedule schedule
;
304 memcpy(password
, pw
.data
, min(pw
.length
, sizeof(password
)));
305 if(pw
.length
< sizeof(password
)) {
306 int len
= min(cell
.length
, sizeof(password
) - pw
.length
);
309 memcpy(password
+ pw
.length
, cell
.data
, len
);
310 for (i
= pw
.length
; i
< pw
.length
+ len
; ++i
)
311 password
[i
] = tolower((unsigned char)password
[i
]);
313 passlen
= min(sizeof(password
), pw
.length
+ cell
.length
);
314 memcpy(&ivec
, "kerberos", 8);
315 memcpy(&temp_key
, "kerberos", 8);
316 DES_set_odd_parity (&temp_key
);
317 DES_set_key (&temp_key
, &schedule
);
318 DES_cbc_cksum ((void*)password
, &ivec
, passlen
, &schedule
, &ivec
);
320 memcpy(&temp_key
, &ivec
, 8);
321 DES_set_odd_parity (&temp_key
);
322 DES_set_key (&temp_key
, &schedule
);
323 DES_cbc_cksum ((void*)password
, key
, passlen
, &schedule
, &ivec
);
324 memset(&schedule
, 0, sizeof(schedule
));
325 memset(&temp_key
, 0, sizeof(temp_key
));
326 memset(&ivec
, 0, sizeof(ivec
));
327 memset(password
, 0, sizeof(password
));
329 DES_set_odd_parity (key
);
332 static krb5_error_code
333 DES_AFS3_string_to_key(krb5_context context
,
334 krb5_enctype enctype
,
341 if(password
.length
> 8)
342 krb5_DES_AFS3_Transarc_string_to_key(password
, salt
.saltvalue
, &tmp
);
344 krb5_DES_AFS3_CMU_string_to_key(password
, salt
.saltvalue
, &tmp
);
345 key
->keytype
= enctype
;
346 krb5_data_copy(&key
->keyvalue
, tmp
, sizeof(tmp
));
347 memset(&key
, 0, sizeof(key
));
350 #endif /* ENABLE_AFS_STRING_TO_KEY */
353 krb5_DES_random_to_key(krb5_context context
,
358 DES_cblock
*k
= key
->keyvalue
.data
;
359 memcpy(k
, data
, key
->keyvalue
.length
);
360 DES_set_odd_parity(k
);
361 if(DES_is_weak_key(k
))
362 xor(k
, (const unsigned char*)"\0\0\0\0\0\0\0\xf0");
370 DES3_random_key(krb5_context context
,
373 DES_cblock
*k
= key
->keyvalue
.data
;
375 krb5_generate_random_block(k
, 3 * sizeof(DES_cblock
));
376 DES_set_odd_parity(&k
[0]);
377 DES_set_odd_parity(&k
[1]);
378 DES_set_odd_parity(&k
[2]);
379 } while(DES_is_weak_key(&k
[0]) ||
380 DES_is_weak_key(&k
[1]) ||
381 DES_is_weak_key(&k
[2]));
385 DES3_schedule(krb5_context context
,
386 struct key_data
*key
,
389 DES_cblock
*k
= key
->key
->keyvalue
.data
;
390 DES_key_schedule
*s
= key
->schedule
->data
;
391 DES_set_key(&k
[0], &s
[0]);
392 DES_set_key(&k
[1], &s
[1]);
393 DES_set_key(&k
[2], &s
[2]);
397 * A = A xor B. A & B are 8 bytes.
401 xor (DES_cblock
*key
, const unsigned char *b
)
403 unsigned char *a
= (unsigned char*)key
;
414 static krb5_error_code
415 DES3_string_to_key(krb5_context context
,
416 krb5_enctype enctype
,
424 unsigned char tmp
[24];
427 len
= password
.length
+ salt
.saltvalue
.length
;
429 if(len
!= 0 && str
== NULL
) {
430 krb5_set_error_string(context
, "malloc: out of memory");
433 memcpy(str
, password
.data
, password
.length
);
434 memcpy(str
+ password
.length
, salt
.saltvalue
.data
, salt
.saltvalue
.length
);
437 DES_key_schedule s
[3];
440 _krb5_n_fold(str
, len
, tmp
, 24);
442 for(i
= 0; i
< 3; i
++){
443 memcpy(keys
+ i
, tmp
+ i
* 8, sizeof(keys
[i
]));
444 DES_set_odd_parity(keys
+ i
);
445 if(DES_is_weak_key(keys
+ i
))
446 xor(keys
+ i
, (const unsigned char*)"\0\0\0\0\0\0\0\xf0");
447 DES_set_key(keys
+ i
, &s
[i
]);
449 memset(&ivec
, 0, sizeof(ivec
));
450 DES_ede3_cbc_encrypt(tmp
,
452 &s
[0], &s
[1], &s
[2], &ivec
, DES_ENCRYPT
);
453 memset(s
, 0, sizeof(s
));
454 memset(&ivec
, 0, sizeof(ivec
));
455 for(i
= 0; i
< 3; i
++){
456 memcpy(keys
+ i
, tmp
+ i
* 8, sizeof(keys
[i
]));
457 DES_set_odd_parity(keys
+ i
);
458 if(DES_is_weak_key(keys
+ i
))
459 xor(keys
+ i
, (const unsigned char*)"\0\0\0\0\0\0\0\xf0");
461 memset(tmp
, 0, sizeof(tmp
));
463 key
->keytype
= enctype
;
464 krb5_data_copy(&key
->keyvalue
, keys
, sizeof(keys
));
465 memset(keys
, 0, sizeof(keys
));
471 static krb5_error_code
472 DES3_string_to_key_derived(krb5_context context
,
473 krb5_enctype enctype
,
480 size_t len
= password
.length
+ salt
.saltvalue
.length
;
484 if(len
!= 0 && s
== NULL
) {
485 krb5_set_error_string(context
, "malloc: out of memory");
488 memcpy(s
, password
.data
, password
.length
);
489 memcpy(s
+ password
.length
, salt
.saltvalue
.data
, salt
.saltvalue
.length
);
490 ret
= krb5_string_to_key_derived(context
,
501 DES3_random_to_key(krb5_context context
,
506 unsigned char *x
= key
->keyvalue
.data
;
507 const u_char
*q
= data
;
511 memset(x
, 0, sizeof(x
));
512 for (i
= 0; i
< 3; ++i
) {
514 for (j
= 0; j
< 7; ++j
) {
515 unsigned char b
= q
[7 * i
+ j
];
520 for (j
= 6; j
>= 0; --j
) {
521 foo
|= q
[7 * i
+ j
] & 1;
526 k
= key
->keyvalue
.data
;
527 for (i
= 0; i
< 3; i
++) {
528 DES_set_odd_parity(&k
[i
]);
529 if(DES_is_weak_key(&k
[i
]))
530 xor(&k
[i
], (const unsigned char*)"\0\0\0\0\0\0\0\xf0");
539 ARCFOUR_schedule(krb5_context context
,
543 RC4_set_key (kd
->schedule
->data
,
544 kd
->key
->keyvalue
.length
, kd
->key
->keyvalue
.data
);
547 static krb5_error_code
548 ARCFOUR_string_to_key(krb5_context context
,
549 krb5_enctype enctype
,
560 len
= 2 * password
.length
;
562 if (len
!= 0 && s
== NULL
) {
563 krb5_set_error_string(context
, "malloc: out of memory");
566 for (p
= s
, i
= 0; i
< password
.length
; ++i
) {
567 *p
++ = ((char *)password
.data
)[i
];
571 MD4_Update (&m
, s
, len
);
572 key
->keytype
= enctype
;
573 krb5_data_alloc (&key
->keyvalue
, 16);
574 MD4_Final (key
->keyvalue
.data
, &m
);
584 /* iter is really 1 based, so iter == 0 will be 1 iteration */
586 krb5_error_code KRB5_LIB_FUNCTION
587 _krb5_PKCS5_PBKDF2(krb5_context context
, krb5_cksumtype cktype
,
588 krb5_data password
, krb5_salt salt
, u_int32_t iter
,
589 krb5_keytype type
, krb5_keyblock
*key
)
591 struct checksum_type
*c
= _find_checksum(cktype
);
593 size_t datalen
, leftofkey
;
596 struct key_data ksign
;
599 char *data
, *tmpcksum
;
604 krb5_set_error_string(context
, "checksum %d not supported", cktype
);
605 return KRB5_PROG_KEYTYPE_NOSUPP
;
608 kt
= _find_keytype(type
);
610 krb5_set_error_string(context
, "key type %d not supported", type
);
611 return KRB5_PROG_KEYTYPE_NOSUPP
;
615 ret
= krb5_data_alloc (&key
->keyvalue
, kt
->bits
/ 8);
617 krb5_set_error_string(context
, "malloc: out of memory");
621 ret
= krb5_data_alloc (&result
.checksum
, c
->checksumsize
);
623 krb5_set_error_string(context
, "malloc: out of memory");
624 krb5_data_free (&key
->keyvalue
);
628 tmpcksum
= malloc(c
->checksumsize
);
629 if (tmpcksum
== NULL
) {
630 krb5_set_error_string(context
, "malloc: out of memory");
631 krb5_data_free (&key
->keyvalue
);
632 krb5_data_free (&result
.checksum
);
636 datalen
= salt
.saltvalue
.length
+ 4;
637 data
= malloc(datalen
);
639 krb5_set_error_string(context
, "malloc: out of memory");
641 krb5_data_free (&key
->keyvalue
);
642 krb5_data_free (&result
.checksum
);
646 kb
.keyvalue
= password
;
649 memcpy(data
, salt
.saltvalue
.data
, salt
.saltvalue
.length
);
652 leftofkey
= key
->keyvalue
.length
;
653 p
= key
->keyvalue
.data
;
658 if (leftofkey
> c
->checksumsize
)
659 len
= c
->checksumsize
;
663 _krb5_put_int(data
+ datalen
- 4, keypart
, 4);
665 ret
= hmac(context
, c
, data
, datalen
, 0, &ksign
, &result
);
667 krb5_abortx(context
, "hmac failed");
668 memcpy(p
, result
.checksum
.data
, len
);
669 memcpy(tmpcksum
, result
.checksum
.data
, result
.checksum
.length
);
670 for (i
= 0; i
< iter
; i
++) {
671 ret
= hmac(context
, c
, tmpcksum
, result
.checksum
.length
,
674 krb5_abortx(context
, "hmac failed");
675 memcpy(tmpcksum
, result
.checksum
.data
, result
.checksum
.length
);
676 for (j
= 0; j
< len
; j
++)
687 krb5_data_free (&result
.checksum
);
692 int _krb5_AES_string_to_default_iterator
= 4096;
694 static krb5_error_code
695 AES_string_to_key(krb5_context context
,
696 krb5_enctype enctype
,
704 struct encryption_type
*et
;
707 if (opaque
.length
== 0)
708 iter
= _krb5_AES_string_to_default_iterator
- 1;
709 else if (opaque
.length
== 4) {
711 _krb5_get_int(opaque
.data
, &v
, 4);
712 iter
= ((u_int32_t
)v
) - 1;
714 return KRB5_PROG_KEYTYPE_NOSUPP
; /* XXX */
717 et
= _find_enctype(enctype
);
719 return KRB5_PROG_KEYTYPE_NOSUPP
;
721 ret
= _krb5_PKCS5_PBKDF2(context
, CKSUMTYPE_SHA1
, password
, salt
,
726 ret
= krb5_copy_keyblock(context
, key
, &kd
.key
);
729 ret
= derive_key(context
, et
, &kd
, "kerberos", strlen("kerberos"));
730 krb5_free_keyblock_contents(context
, key
);
732 ret
= krb5_copy_keyblock_contents(context
, kd
.key
, key
);
733 free_key_data(context
, &kd
);
739 struct krb5_aes_schedule
{
745 AES_schedule(krb5_context context
,
749 struct krb5_aes_schedule
*key
= kd
->schedule
->data
;
750 int bits
= kd
->key
->keyvalue
.length
* 8;
752 memset(key
, 0, sizeof(*key
));
753 AES_set_encrypt_key(kd
->key
->keyvalue
.data
, bits
, &key
->ekey
);
754 AES_set_decrypt_key(kd
->key
->keyvalue
.data
, bits
, &key
->dkey
);
762 int maximum_effective_key
;
765 static krb5_error_code
766 rc2_get_params(krb5_context context
,
767 const krb5_data
*data
,
771 RC2CBCParameter rc2params
;
772 struct _RC2_params
*p
;
776 ret
= decode_RC2CBCParameter(data
->data
, data
->length
, &rc2params
, &size
);
778 krb5_set_error_string(context
, "Can't decode RC2 parameters");
781 p
= malloc(sizeof(*p
));
783 free_RC2CBCParameter(&rc2params
);
784 krb5_set_error_string(context
, "malloc - out of memory");
788 switch(rc2params
.rc2ParameterVersion
) {
790 p
->maximum_effective_key
= 40;
793 p
->maximum_effective_key
= 64;
796 p
->maximum_effective_key
= 128;
801 ret
= copy_octet_string(&rc2params
.iv
, ivec
);
802 free_RC2CBCParameter(&rc2params
);
808 static krb5_error_code
809 rc2_set_params(krb5_context context
,
811 const krb5_data
*ivec
,
814 RC2CBCParameter rc2params
;
815 const struct _RC2_params
*p
= params
;
816 int maximum_effective_key
= 128;
820 memset(&rc2params
, 0, sizeof(rc2params
));
823 maximum_effective_key
= p
->maximum_effective_key
;
826 switch(maximum_effective_key
) {
828 rc2params
.rc2ParameterVersion
= 160;
831 rc2params
.rc2ParameterVersion
= 120;
834 rc2params
.rc2ParameterVersion
= 58;
837 ret
= copy_octet_string(ivec
, &rc2params
.iv
);
841 ASN1_MALLOC_ENCODE(RC2CBCParameter
, data
->data
, data
->length
,
842 &rc2params
, &size
, ret
);
843 if (ret
== 0 && size
!= data
->length
)
844 krb5_abortx(context
, "Internal asn1 encoder failure");
845 free_RC2CBCParameter(&rc2params
);
851 rc2_schedule(krb5_context context
,
855 const struct _RC2_params
*p
= params
;
856 int maximum_effective_key
= 128;
858 maximum_effective_key
= p
->maximum_effective_key
;
859 RC2_set_key (kd
->schedule
->data
,
860 kd
->key
->keyvalue
.length
,
861 kd
->key
->keyvalue
.data
,
862 maximum_effective_key
);
870 static struct salt_type des_salt
[] = {
874 krb5_DES_string_to_key
876 #ifdef ENABLE_AFS_STRING_TO_KEY
880 DES_AFS3_string_to_key
886 static struct salt_type des3_salt
[] = {
895 static struct salt_type des3_salt_derived
[] = {
899 DES3_string_to_key_derived
904 static struct salt_type AES_salt
[] = {
913 static struct salt_type arcfour_salt
[] = {
917 ARCFOUR_string_to_key
926 static struct key_type keytype_null
= {
938 static struct key_type keytype_des
= {
944 sizeof(DES_key_schedule
),
948 krb5_DES_random_to_key
951 static struct key_type keytype_des3
= {
955 3 * sizeof(DES_cblock
),
956 3 * sizeof(DES_cblock
),
957 3 * sizeof(DES_key_schedule
),
964 static struct key_type keytype_des3_derived
= {
968 3 * sizeof(DES_cblock
),
969 3 * sizeof(DES_cblock
),
970 3 * sizeof(DES_key_schedule
),
977 static struct key_type keytype_aes128
= {
983 sizeof(struct krb5_aes_schedule
),
989 static struct key_type keytype_aes192
= {
995 sizeof(struct krb5_aes_schedule
),
1001 static struct key_type keytype_aes256
= {
1007 sizeof(struct krb5_aes_schedule
),
1013 static struct key_type keytype_arcfour
= {
1025 static struct key_type keytype_rc2
= {
1034 NULL
, /* XXX salt */
1040 static struct key_type
*keytypes
[] = {
1043 &keytype_des3_derived
,
1052 static int num_keytypes
= sizeof(keytypes
) / sizeof(keytypes
[0]);
1054 static struct key_type
*
1055 _find_keytype(krb5_keytype type
)
1058 for(i
= 0; i
< num_keytypes
; i
++)
1059 if(keytypes
[i
]->type
== type
)
1065 krb5_error_code KRB5_LIB_FUNCTION
1066 krb5_salttype_to_string (krb5_context context
,
1068 krb5_salttype stype
,
1071 struct encryption_type
*e
;
1072 struct salt_type
*st
;
1074 e
= _find_enctype (etype
);
1076 krb5_set_error_string(context
, "encryption type %d not supported",
1078 return KRB5_PROG_ETYPE_NOSUPP
;
1080 for (st
= e
->keytype
->string_to_key
; st
&& st
->type
; st
++) {
1081 if (st
->type
== stype
) {
1082 *string
= strdup (st
->name
);
1083 if (*string
== NULL
) {
1084 krb5_set_error_string(context
, "malloc: out of memory");
1090 krb5_set_error_string(context
, "salttype %d not supported", stype
);
1091 return HEIM_ERR_SALTTYPE_NOSUPP
;
1094 krb5_error_code KRB5_LIB_FUNCTION
1095 krb5_string_to_salttype (krb5_context context
,
1098 krb5_salttype
*salttype
)
1100 struct encryption_type
*e
;
1101 struct salt_type
*st
;
1103 e
= _find_enctype (etype
);
1105 krb5_set_error_string(context
, "encryption type %d not supported",
1107 return KRB5_PROG_ETYPE_NOSUPP
;
1109 for (st
= e
->keytype
->string_to_key
; st
&& st
->type
; st
++) {
1110 if (strcasecmp (st
->name
, string
) == 0) {
1111 *salttype
= st
->type
;
1115 krb5_set_error_string(context
, "salttype %s not supported", string
);
1116 return HEIM_ERR_SALTTYPE_NOSUPP
;
1119 krb5_error_code KRB5_LIB_FUNCTION
1120 krb5_get_pw_salt(krb5_context context
,
1121 krb5_const_principal principal
,
1126 krb5_error_code ret
;
1129 salt
->salttype
= KRB5_PW_SALT
;
1130 len
= strlen(principal
->realm
);
1131 for (i
= 0; i
< principal
->name
.name_string
.len
; ++i
)
1132 len
+= strlen(principal
->name
.name_string
.val
[i
]);
1133 ret
= krb5_data_alloc (&salt
->saltvalue
, len
);
1136 p
= salt
->saltvalue
.data
;
1137 memcpy (p
, principal
->realm
, strlen(principal
->realm
));
1138 p
+= strlen(principal
->realm
);
1139 for (i
= 0; i
< principal
->name
.name_string
.len
; ++i
) {
1141 principal
->name
.name_string
.val
[i
],
1142 strlen(principal
->name
.name_string
.val
[i
]));
1143 p
+= strlen(principal
->name
.name_string
.val
[i
]);
1148 krb5_error_code KRB5_LIB_FUNCTION
1149 krb5_free_salt(krb5_context context
,
1152 krb5_data_free(&salt
.saltvalue
);
1156 krb5_error_code KRB5_LIB_FUNCTION
1157 krb5_string_to_key_data (krb5_context context
,
1158 krb5_enctype enctype
,
1160 krb5_principal principal
,
1163 krb5_error_code ret
;
1166 ret
= krb5_get_pw_salt(context
, principal
, &salt
);
1169 ret
= krb5_string_to_key_data_salt(context
, enctype
, password
, salt
, key
);
1170 krb5_free_salt(context
, salt
);
1174 krb5_error_code KRB5_LIB_FUNCTION
1175 krb5_string_to_key (krb5_context context
,
1176 krb5_enctype enctype
,
1177 const char *password
,
1178 krb5_principal principal
,
1182 pw
.data
= rk_UNCONST(password
);
1183 pw
.length
= strlen(password
);
1184 return krb5_string_to_key_data(context
, enctype
, pw
, principal
, key
);
1187 krb5_error_code KRB5_LIB_FUNCTION
1188 krb5_string_to_key_data_salt (krb5_context context
,
1189 krb5_enctype enctype
,
1195 krb5_data_zero(&opaque
);
1196 return krb5_string_to_key_data_salt_opaque(context
, enctype
, password
,
1201 * Do a string -> key for encryption type `enctype' operation on
1202 * `password' (with salt `salt' and the enctype specific data string
1203 * `opaque'), returning the resulting key in `key'
1206 krb5_error_code KRB5_LIB_FUNCTION
1207 krb5_string_to_key_data_salt_opaque (krb5_context context
,
1208 krb5_enctype enctype
,
1214 struct encryption_type
*et
=_find_enctype(enctype
);
1215 struct salt_type
*st
;
1217 krb5_set_error_string(context
, "encryption type %d not supported",
1219 return KRB5_PROG_ETYPE_NOSUPP
;
1221 for(st
= et
->keytype
->string_to_key
; st
&& st
->type
; st
++)
1222 if(st
->type
== salt
.salttype
)
1223 return (*st
->string_to_key
)(context
, enctype
, password
,
1225 krb5_set_error_string(context
, "salt type %d not supported",
1227 return HEIM_ERR_SALTTYPE_NOSUPP
;
1231 * Do a string -> key for encryption type `enctype' operation on the
1232 * string `password' (with salt `salt'), returning the resulting key
1236 krb5_error_code KRB5_LIB_FUNCTION
1237 krb5_string_to_key_salt (krb5_context context
,
1238 krb5_enctype enctype
,
1239 const char *password
,
1244 pw
.data
= rk_UNCONST(password
);
1245 pw
.length
= strlen(password
);
1246 return krb5_string_to_key_data_salt(context
, enctype
, pw
, salt
, key
);
1249 krb5_error_code KRB5_LIB_FUNCTION
1250 krb5_string_to_key_salt_opaque (krb5_context context
,
1251 krb5_enctype enctype
,
1252 const char *password
,
1258 pw
.data
= rk_UNCONST(password
);
1259 pw
.length
= strlen(password
);
1260 return krb5_string_to_key_data_salt_opaque(context
, enctype
,
1261 pw
, salt
, opaque
, key
);
1264 krb5_error_code KRB5_LIB_FUNCTION
1265 krb5_keytype_to_string(krb5_context context
,
1266 krb5_keytype keytype
,
1269 struct key_type
*kt
= _find_keytype(keytype
);
1271 krb5_set_error_string(context
, "key type %d not supported", keytype
);
1272 return KRB5_PROG_KEYTYPE_NOSUPP
;
1274 *string
= strdup(kt
->name
);
1275 if(*string
== NULL
) {
1276 krb5_set_error_string(context
, "malloc: out of memory");
1282 krb5_error_code KRB5_LIB_FUNCTION
1283 krb5_string_to_keytype(krb5_context context
,
1285 krb5_keytype
*keytype
)
1288 for(i
= 0; i
< num_keytypes
; i
++)
1289 if(strcasecmp(keytypes
[i
]->name
, string
) == 0){
1290 *keytype
= keytypes
[i
]->type
;
1293 krb5_set_error_string(context
, "key type %s not supported", string
);
1294 return KRB5_PROG_KEYTYPE_NOSUPP
;
1297 krb5_error_code KRB5_LIB_FUNCTION
1298 krb5_enctype_keysize(krb5_context context
,
1302 struct encryption_type
*et
= _find_enctype(type
);
1304 krb5_set_error_string(context
, "encryption type %d not supported",
1306 return KRB5_PROG_ETYPE_NOSUPP
;
1308 *keysize
= et
->keytype
->size
;
1312 krb5_error_code KRB5_LIB_FUNCTION
1313 krb5_generate_random_keyblock(krb5_context context
,
1317 krb5_error_code ret
;
1318 struct encryption_type
*et
= _find_enctype(type
);
1320 krb5_set_error_string(context
, "encryption type %d not supported",
1322 return KRB5_PROG_ETYPE_NOSUPP
;
1324 ret
= krb5_data_alloc(&key
->keyvalue
, et
->keytype
->size
);
1327 key
->keytype
= type
;
1328 if(et
->keytype
->random_key
)
1329 (*et
->keytype
->random_key
)(context
, key
);
1331 krb5_generate_random_block(key
->keyvalue
.data
,
1332 key
->keyvalue
.length
);
1336 static krb5_error_code
1337 _key_schedule(krb5_context context
,
1338 struct key_data
*key
,
1341 krb5_error_code ret
;
1342 struct encryption_type
*et
= _find_enctype(key
->key
->keytype
);
1343 struct key_type
*kt
= et
->keytype
;
1345 if(kt
->schedule
== NULL
)
1347 if (key
->schedule
!= NULL
)
1349 ALLOC(key
->schedule
, 1);
1350 if(key
->schedule
== NULL
) {
1351 krb5_set_error_string(context
, "malloc: out of memory");
1354 ret
= krb5_data_alloc(key
->schedule
, kt
->schedule_size
);
1356 free(key
->schedule
);
1357 key
->schedule
= NULL
;
1360 (*kt
->schedule
)(context
, key
, params
);
1364 /************************************************************
1366 ************************************************************/
1369 NONE_checksum(krb5_context context
,
1370 struct key_data
*key
,
1379 CRC32_checksum(krb5_context context
,
1380 struct key_data
*key
,
1387 unsigned char *r
= C
->checksum
.data
;
1388 _krb5_crc_init_table ();
1389 crc
= _krb5_crc_update (data
, len
, 0);
1391 r
[1] = (crc
>> 8) & 0xff;
1392 r
[2] = (crc
>> 16) & 0xff;
1393 r
[3] = (crc
>> 24) & 0xff;
1397 RSA_MD4_checksum(krb5_context context
,
1398 struct key_data
*key
,
1407 MD4_Update (&m
, data
, len
);
1408 MD4_Final (C
->checksum
.data
, &m
);
1412 RSA_MD4_DES_checksum(krb5_context context
,
1413 struct key_data
*key
,
1421 unsigned char *p
= cksum
->checksum
.data
;
1423 krb5_generate_random_block(p
, 8);
1425 MD4_Update (&md4
, p
, 8);
1426 MD4_Update (&md4
, data
, len
);
1427 MD4_Final (p
+ 8, &md4
);
1428 memset (&ivec
, 0, sizeof(ivec
));
1432 key
->schedule
->data
,
1437 static krb5_error_code
1438 RSA_MD4_DES_verify(krb5_context context
,
1439 struct key_data
*key
,
1446 unsigned char tmp
[24];
1447 unsigned char res
[16];
1449 krb5_error_code ret
= 0;
1451 memset(&ivec
, 0, sizeof(ivec
));
1452 DES_cbc_encrypt(C
->checksum
.data
,
1455 key
->schedule
->data
,
1459 MD4_Update (&md4
, tmp
, 8); /* confounder */
1460 MD4_Update (&md4
, data
, len
);
1461 MD4_Final (res
, &md4
);
1462 if(memcmp(res
, tmp
+ 8, sizeof(res
)) != 0) {
1463 krb5_clear_error_string (context
);
1464 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
1466 memset(tmp
, 0, sizeof(tmp
));
1467 memset(res
, 0, sizeof(res
));
1472 RSA_MD5_checksum(krb5_context context
,
1473 struct key_data
*key
,
1482 MD5_Update(&m
, data
, len
);
1483 MD5_Final (C
->checksum
.data
, &m
);
1487 RSA_MD5_DES_checksum(krb5_context context
,
1488 struct key_data
*key
,
1496 unsigned char *p
= C
->checksum
.data
;
1498 krb5_generate_random_block(p
, 8);
1500 MD5_Update (&md5
, p
, 8);
1501 MD5_Update (&md5
, data
, len
);
1502 MD5_Final (p
+ 8, &md5
);
1503 memset (&ivec
, 0, sizeof(ivec
));
1507 key
->schedule
->data
,
1512 static krb5_error_code
1513 RSA_MD5_DES_verify(krb5_context context
,
1514 struct key_data
*key
,
1521 unsigned char tmp
[24];
1522 unsigned char res
[16];
1524 DES_key_schedule
*sched
= key
->schedule
->data
;
1525 krb5_error_code ret
= 0;
1527 memset(&ivec
, 0, sizeof(ivec
));
1528 DES_cbc_encrypt(C
->checksum
.data
,
1535 MD5_Update (&md5
, tmp
, 8); /* confounder */
1536 MD5_Update (&md5
, data
, len
);
1537 MD5_Final (res
, &md5
);
1538 if(memcmp(res
, tmp
+ 8, sizeof(res
)) != 0) {
1539 krb5_clear_error_string (context
);
1540 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
1542 memset(tmp
, 0, sizeof(tmp
));
1543 memset(res
, 0, sizeof(res
));
1548 RSA_MD5_DES3_checksum(krb5_context context
,
1549 struct key_data
*key
,
1557 unsigned char *p
= C
->checksum
.data
;
1558 DES_key_schedule
*sched
= key
->schedule
->data
;
1560 krb5_generate_random_block(p
, 8);
1562 MD5_Update (&md5
, p
, 8);
1563 MD5_Update (&md5
, data
, len
);
1564 MD5_Final (p
+ 8, &md5
);
1565 memset (&ivec
, 0, sizeof(ivec
));
1566 DES_ede3_cbc_encrypt(p
,
1569 &sched
[0], &sched
[1], &sched
[2],
1574 static krb5_error_code
1575 RSA_MD5_DES3_verify(krb5_context context
,
1576 struct key_data
*key
,
1583 unsigned char tmp
[24];
1584 unsigned char res
[16];
1586 DES_key_schedule
*sched
= key
->schedule
->data
;
1587 krb5_error_code ret
= 0;
1589 memset(&ivec
, 0, sizeof(ivec
));
1590 DES_ede3_cbc_encrypt(C
->checksum
.data
,
1593 &sched
[0], &sched
[1], &sched
[2],
1597 MD5_Update (&md5
, tmp
, 8); /* confounder */
1598 MD5_Update (&md5
, data
, len
);
1599 MD5_Final (res
, &md5
);
1600 if(memcmp(res
, tmp
+ 8, sizeof(res
)) != 0) {
1601 krb5_clear_error_string (context
);
1602 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
1604 memset(tmp
, 0, sizeof(tmp
));
1605 memset(res
, 0, sizeof(res
));
1610 SHA1_checksum(krb5_context context
,
1611 struct key_data
*key
,
1620 SHA1_Update(&m
, data
, len
);
1621 SHA1_Final(C
->checksum
.data
, &m
);
1624 /* HMAC according to RFC2104 */
1625 static krb5_error_code
1626 hmac(krb5_context context
,
1627 struct checksum_type
*cm
,
1631 struct key_data
*keyblock
,
1634 unsigned char *ipad
, *opad
;
1639 ipad
= malloc(cm
->blocksize
+ len
);
1642 opad
= malloc(cm
->blocksize
+ cm
->checksumsize
);
1647 memset(ipad
, 0x36, cm
->blocksize
);
1648 memset(opad
, 0x5c, cm
->blocksize
);
1650 if(keyblock
->key
->keyvalue
.length
> cm
->blocksize
){
1651 (*cm
->checksum
)(context
,
1653 keyblock
->key
->keyvalue
.data
,
1654 keyblock
->key
->keyvalue
.length
,
1657 key
= result
->checksum
.data
;
1658 key_len
= result
->checksum
.length
;
1660 key
= keyblock
->key
->keyvalue
.data
;
1661 key_len
= keyblock
->key
->keyvalue
.length
;
1663 for(i
= 0; i
< key_len
; i
++){
1667 memcpy(ipad
+ cm
->blocksize
, data
, len
);
1668 (*cm
->checksum
)(context
, keyblock
, ipad
, cm
->blocksize
+ len
,
1670 memcpy(opad
+ cm
->blocksize
, result
->checksum
.data
,
1671 result
->checksum
.length
);
1672 (*cm
->checksum
)(context
, keyblock
, opad
,
1673 cm
->blocksize
+ cm
->checksumsize
, usage
, result
);
1674 memset(ipad
, 0, cm
->blocksize
+ len
);
1676 memset(opad
, 0, cm
->blocksize
+ cm
->checksumsize
);
1682 krb5_error_code KRB5_LIB_FUNCTION
1683 krb5_hmac(krb5_context context
,
1684 krb5_cksumtype cktype
,
1691 struct checksum_type
*c
= _find_checksum(cktype
);
1693 krb5_error_code ret
;
1696 krb5_set_error_string (context
, "checksum type %d not supported",
1698 return KRB5_PROG_SUMTYPE_NOSUPP
;
1704 ret
= hmac(context
, c
, data
, len
, usage
, &kd
, result
);
1707 krb5_free_data(context
, kd
.schedule
);
1713 SP_HMAC_SHA1_checksum(krb5_context context
,
1714 struct key_data
*key
,
1720 struct checksum_type
*c
= _find_checksum(CKSUMTYPE_SHA1
);
1723 krb5_error_code ret
;
1725 res
.checksum
.data
= sha1_data
;
1726 res
.checksum
.length
= sizeof(sha1_data
);
1728 ret
= hmac(context
, c
, data
, len
, usage
, key
, &res
);
1730 krb5_abortx(context
, "hmac failed");
1731 memcpy(result
->checksum
.data
, res
.checksum
.data
, result
->checksum
.length
);
1735 * checksum according to section 5. of draft-brezak-win2k-krb-rc4-hmac-03.txt
1739 HMAC_MD5_checksum(krb5_context context
,
1740 struct key_data
*key
,
1747 struct checksum_type
*c
= _find_checksum (CKSUMTYPE_RSA_MD5
);
1748 const char signature
[] = "signaturekey";
1750 struct key_data ksign
;
1753 unsigned char tmp
[16];
1754 unsigned char ksign_c_data
[16];
1755 krb5_error_code ret
;
1757 ksign_c
.checksum
.length
= sizeof(ksign_c_data
);
1758 ksign_c
.checksum
.data
= ksign_c_data
;
1759 ret
= hmac(context
, c
, signature
, sizeof(signature
), 0, key
, &ksign_c
);
1761 krb5_abortx(context
, "hmac failed");
1763 kb
.keyvalue
= ksign_c
.checksum
;
1765 t
[0] = (usage
>> 0) & 0xFF;
1766 t
[1] = (usage
>> 8) & 0xFF;
1767 t
[2] = (usage
>> 16) & 0xFF;
1768 t
[3] = (usage
>> 24) & 0xFF;
1769 MD5_Update (&md5
, t
, 4);
1770 MD5_Update (&md5
, data
, len
);
1771 MD5_Final (tmp
, &md5
);
1772 ret
= hmac(context
, c
, tmp
, sizeof(tmp
), 0, &ksign
, result
);
1774 krb5_abortx(context
, "hmac failed");
1778 * same as previous but being used while encrypting.
1782 HMAC_MD5_checksum_enc(krb5_context context
,
1783 struct key_data
*key
,
1789 struct checksum_type
*c
= _find_checksum (CKSUMTYPE_RSA_MD5
);
1791 struct key_data ksign
;
1794 unsigned char ksign_c_data
[16];
1795 krb5_error_code ret
;
1797 t
[0] = (usage
>> 0) & 0xFF;
1798 t
[1] = (usage
>> 8) & 0xFF;
1799 t
[2] = (usage
>> 16) & 0xFF;
1800 t
[3] = (usage
>> 24) & 0xFF;
1802 ksign_c
.checksum
.length
= sizeof(ksign_c_data
);
1803 ksign_c
.checksum
.data
= ksign_c_data
;
1804 ret
= hmac(context
, c
, t
, sizeof(t
), 0, key
, &ksign_c
);
1806 krb5_abortx(context
, "hmac failed");
1808 kb
.keyvalue
= ksign_c
.checksum
;
1809 ret
= hmac(context
, c
, data
, len
, 0, &ksign
, result
);
1811 krb5_abortx(context
, "hmac failed");
1814 static struct checksum_type checksum_none
= {
1823 static struct checksum_type checksum_crc32
= {
1832 static struct checksum_type checksum_rsa_md4
= {
1841 static struct checksum_type checksum_rsa_md4_des
= {
1842 CKSUMTYPE_RSA_MD4_DES
,
1846 F_KEYED
| F_CPROOF
| F_VARIANT
,
1847 RSA_MD4_DES_checksum
,
1851 static struct checksum_type checksum_des_mac
= {
1859 static struct checksum_type checksum_des_mac_k
= {
1860 CKSUMTYPE_DES_MAC_K
,
1867 static struct checksum_type checksum_rsa_md4_des_k
= {
1868 CKSUMTYPE_RSA_MD4_DES_K
,
1873 RSA_MD4_DES_K_checksum
,
1874 RSA_MD4_DES_K_verify
1877 static struct checksum_type checksum_rsa_md5
= {
1886 static struct checksum_type checksum_rsa_md5_des
= {
1887 CKSUMTYPE_RSA_MD5_DES
,
1891 F_KEYED
| F_CPROOF
| F_VARIANT
,
1892 RSA_MD5_DES_checksum
,
1895 static struct checksum_type checksum_rsa_md5_des3
= {
1896 CKSUMTYPE_RSA_MD5_DES3
,
1900 F_KEYED
| F_CPROOF
| F_VARIANT
,
1901 RSA_MD5_DES3_checksum
,
1904 static struct checksum_type checksum_sha1
= {
1913 static struct checksum_type checksum_hmac_sha1_des3
= {
1914 CKSUMTYPE_HMAC_SHA1_DES3
,
1918 F_KEYED
| F_CPROOF
| F_DERIVED
,
1919 SP_HMAC_SHA1_checksum
,
1923 static struct checksum_type checksum_hmac_sha1_aes128
= {
1924 CKSUMTYPE_HMAC_SHA1_96_AES_128
,
1925 "hmac-sha1-96-aes128",
1928 F_KEYED
| F_CPROOF
| F_DERIVED
,
1929 SP_HMAC_SHA1_checksum
,
1933 static struct checksum_type checksum_hmac_sha1_aes256
= {
1934 CKSUMTYPE_HMAC_SHA1_96_AES_256
,
1935 "hmac-sha1-96-aes256",
1938 F_KEYED
| F_CPROOF
| F_DERIVED
,
1939 SP_HMAC_SHA1_checksum
,
1943 static struct checksum_type checksum_hmac_md5
= {
1953 static struct checksum_type checksum_hmac_md5_enc
= {
1954 CKSUMTYPE_HMAC_MD5_ENC
,
1958 F_KEYED
| F_CPROOF
| F_PSEUDO
,
1959 HMAC_MD5_checksum_enc
,
1963 static struct checksum_type
*checksum_types
[] = {
1967 &checksum_rsa_md4_des
,
1970 &checksum_des_mac_k
,
1971 &checksum_rsa_md4_des_k
,
1974 &checksum_rsa_md5_des
,
1975 &checksum_rsa_md5_des3
,
1977 &checksum_hmac_sha1_des3
,
1978 &checksum_hmac_sha1_aes128
,
1979 &checksum_hmac_sha1_aes256
,
1981 &checksum_hmac_md5_enc
1984 static int num_checksums
= sizeof(checksum_types
) / sizeof(checksum_types
[0]);
1986 static struct checksum_type
*
1987 _find_checksum(krb5_cksumtype type
)
1990 for(i
= 0; i
< num_checksums
; i
++)
1991 if(checksum_types
[i
]->type
== type
)
1992 return checksum_types
[i
];
1996 static krb5_error_code
1997 get_checksum_key(krb5_context context
,
1999 unsigned usage
, /* not krb5_key_usage */
2000 struct checksum_type
*ct
,
2001 struct key_data
**key
)
2003 krb5_error_code ret
= 0;
2005 if(ct
->flags
& F_DERIVED
)
2006 ret
= _get_derived_key(context
, crypto
, usage
, key
);
2007 else if(ct
->flags
& F_VARIANT
) {
2010 *key
= _new_derived_key(crypto
, 0xff/* KRB5_KU_RFC1510_VARIANT */);
2012 krb5_set_error_string(context
, "malloc: out of memory");
2015 ret
= krb5_copy_keyblock(context
, crypto
->key
.key
, &(*key
)->key
);
2018 for(i
= 0; i
< (*key
)->key
->keyvalue
.length
; i
++)
2019 ((unsigned char*)(*key
)->key
->keyvalue
.data
)[i
] ^= 0xF0;
2021 *key
= &crypto
->key
;
2024 ret
= _key_schedule(context
, *key
, crypto
->params
);
2028 static krb5_error_code
2029 create_checksum (krb5_context context
,
2030 struct checksum_type
*ct
,
2037 krb5_error_code ret
;
2038 struct key_data
*dkey
;
2041 if (ct
->flags
& F_DISABLED
) {
2042 krb5_clear_error_string (context
);
2043 return KRB5_PROG_SUMTYPE_NOSUPP
;
2045 keyed_checksum
= (ct
->flags
& F_KEYED
) != 0;
2046 if(keyed_checksum
&& crypto
== NULL
) {
2047 krb5_clear_error_string (context
);
2048 return KRB5_PROG_SUMTYPE_NOSUPP
; /* XXX */
2050 if(keyed_checksum
) {
2051 ret
= get_checksum_key(context
, crypto
, usage
, ct
, &dkey
);
2056 result
->cksumtype
= ct
->type
;
2057 krb5_data_alloc(&result
->checksum
, ct
->checksumsize
);
2058 (*ct
->checksum
)(context
, dkey
, data
, len
, usage
, result
);
2063 arcfour_checksum_p(struct checksum_type
*ct
, krb5_crypto crypto
)
2065 return (ct
->type
== CKSUMTYPE_HMAC_MD5
) &&
2066 (crypto
->key
.key
->keytype
== KEYTYPE_ARCFOUR
);
2069 krb5_error_code KRB5_LIB_FUNCTION
2070 krb5_create_checksum(krb5_context context
,
2072 krb5_key_usage usage
,
2078 struct checksum_type
*ct
= NULL
;
2081 /* type 0 -> pick from crypto */
2083 ct
= _find_checksum(type
);
2084 } else if (crypto
) {
2085 ct
= crypto
->et
->keyed_checksum
;
2087 ct
= crypto
->et
->checksum
;
2091 krb5_set_error_string (context
, "checksum type %d not supported",
2093 return KRB5_PROG_SUMTYPE_NOSUPP
;
2096 if (arcfour_checksum_p(ct
, crypto
)) {
2098 usage2arcfour(context
, &keyusage
);
2100 keyusage
= CHECKSUM_USAGE(usage
);
2102 return create_checksum(context
, ct
, crypto
, keyusage
,
2106 static krb5_error_code
2107 verify_checksum(krb5_context context
,
2109 unsigned usage
, /* not krb5_key_usage */
2114 krb5_error_code ret
;
2115 struct key_data
*dkey
;
2118 struct checksum_type
*ct
;
2120 ct
= _find_checksum(cksum
->cksumtype
);
2121 if (ct
== NULL
|| (ct
->flags
& F_DISABLED
)) {
2122 krb5_set_error_string (context
, "checksum type %d not supported",
2124 return KRB5_PROG_SUMTYPE_NOSUPP
;
2126 if(ct
->checksumsize
!= cksum
->checksum
.length
) {
2127 krb5_clear_error_string (context
);
2128 return KRB5KRB_AP_ERR_BAD_INTEGRITY
; /* XXX */
2130 keyed_checksum
= (ct
->flags
& F_KEYED
) != 0;
2131 if(keyed_checksum
&& crypto
== NULL
) {
2132 krb5_clear_error_string (context
);
2133 return KRB5_PROG_SUMTYPE_NOSUPP
; /* XXX */
2136 ret
= get_checksum_key(context
, crypto
, usage
, ct
, &dkey
);
2140 return (*ct
->verify
)(context
, dkey
, data
, len
, usage
, cksum
);
2142 ret
= krb5_data_alloc (&c
.checksum
, ct
->checksumsize
);
2146 (*ct
->checksum
)(context
, dkey
, data
, len
, usage
, &c
);
2148 if(c
.checksum
.length
!= cksum
->checksum
.length
||
2149 memcmp(c
.checksum
.data
, cksum
->checksum
.data
, c
.checksum
.length
)) {
2150 krb5_clear_error_string (context
);
2151 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
2155 krb5_data_free (&c
.checksum
);
2159 krb5_error_code KRB5_LIB_FUNCTION
2160 krb5_verify_checksum(krb5_context context
,
2162 krb5_key_usage usage
,
2167 struct checksum_type
*ct
;
2170 ct
= _find_checksum(cksum
->cksumtype
);
2172 krb5_set_error_string (context
, "checksum type %d not supported",
2174 return KRB5_PROG_SUMTYPE_NOSUPP
;
2177 if (arcfour_checksum_p(ct
, crypto
)) {
2179 usage2arcfour(context
, &keyusage
);
2181 keyusage
= CHECKSUM_USAGE(usage
);
2183 return verify_checksum(context
, crypto
, keyusage
,
2187 krb5_error_code KRB5_LIB_FUNCTION
2188 krb5_crypto_get_checksum_type(krb5_context context
,
2190 krb5_cksumtype
*type
)
2192 struct checksum_type
*ct
= NULL
;
2194 if (crypto
!= NULL
) {
2195 ct
= crypto
->et
->keyed_checksum
;
2197 ct
= crypto
->et
->checksum
;
2201 krb5_set_error_string (context
, "checksum type not found");
2202 return KRB5_PROG_SUMTYPE_NOSUPP
;
2211 krb5_error_code KRB5_LIB_FUNCTION
2212 krb5_checksumsize(krb5_context context
,
2213 krb5_cksumtype type
,
2216 struct checksum_type
*ct
= _find_checksum(type
);
2218 krb5_set_error_string (context
, "checksum type %d not supported",
2220 return KRB5_PROG_SUMTYPE_NOSUPP
;
2222 *size
= ct
->checksumsize
;
2226 krb5_boolean KRB5_LIB_FUNCTION
2227 krb5_checksum_is_keyed(krb5_context context
,
2228 krb5_cksumtype type
)
2230 struct checksum_type
*ct
= _find_checksum(type
);
2233 krb5_set_error_string (context
, "checksum type %d not supported",
2235 return KRB5_PROG_SUMTYPE_NOSUPP
;
2237 return ct
->flags
& F_KEYED
;
2240 krb5_boolean KRB5_LIB_FUNCTION
2241 krb5_checksum_is_collision_proof(krb5_context context
,
2242 krb5_cksumtype type
)
2244 struct checksum_type
*ct
= _find_checksum(type
);
2247 krb5_set_error_string (context
, "checksum type %d not supported",
2249 return KRB5_PROG_SUMTYPE_NOSUPP
;
2251 return ct
->flags
& F_CPROOF
;
2254 krb5_error_code KRB5_LIB_FUNCTION
2255 krb5_checksum_disable(krb5_context context
,
2256 krb5_cksumtype type
)
2258 struct checksum_type
*ct
= _find_checksum(type
);
2261 krb5_set_error_string (context
, "checksum type %d not supported",
2263 return KRB5_PROG_SUMTYPE_NOSUPP
;
2265 ct
->flags
|= F_DISABLED
;
2269 /************************************************************
2271 ************************************************************/
2273 static krb5_error_code
2274 NULL_encrypt(krb5_context context
,
2275 struct key_data
*key
,
2278 krb5_boolean encryptp
,
2285 static krb5_error_code
2286 DES_CBC_encrypt_null_ivec(krb5_context context
,
2287 struct key_data
*key
,
2290 krb5_boolean encryptp
,
2295 DES_key_schedule
*s
= key
->schedule
->data
;
2296 memset(&ivec
, 0, sizeof(ivec
));
2297 DES_cbc_encrypt(data
, data
, len
, s
, &ivec
, encryptp
);
2301 static krb5_error_code
2302 DES_CBC_encrypt_key_ivec(krb5_context context
,
2303 struct key_data
*key
,
2306 krb5_boolean encryptp
,
2311 DES_key_schedule
*s
= key
->schedule
->data
;
2312 memcpy(&ivec
, key
->key
->keyvalue
.data
, sizeof(ivec
));
2313 DES_cbc_encrypt(data
, data
, len
, s
, &ivec
, encryptp
);
2317 static krb5_error_code
2318 DES3_CBC_encrypt(krb5_context context
,
2319 struct key_data
*key
,
2322 krb5_boolean encryptp
,
2326 DES_cblock local_ivec
;
2327 DES_key_schedule
*s
= key
->schedule
->data
;
2330 memset(local_ivec
, 0, sizeof(local_ivec
));
2332 DES_ede3_cbc_encrypt(data
, data
, len
, &s
[0], &s
[1], &s
[2], ivec
, encryptp
);
2336 static krb5_error_code
2337 DES_CFB64_encrypt_null_ivec(krb5_context context
,
2338 struct key_data
*key
,
2341 krb5_boolean encryptp
,
2347 DES_key_schedule
*s
= key
->schedule
->data
;
2348 memset(&ivec
, 0, sizeof(ivec
));
2350 DES_cfb64_encrypt(data
, data
, len
, s
, &ivec
, &num
, encryptp
);
2354 static krb5_error_code
2355 DES_PCBC_encrypt_key_ivec(krb5_context context
,
2356 struct key_data
*key
,
2359 krb5_boolean encryptp
,
2364 DES_key_schedule
*s
= key
->schedule
->data
;
2365 memcpy(&ivec
, key
->key
->keyvalue
.data
, sizeof(ivec
));
2367 DES_pcbc_encrypt(data
, data
, len
, s
, &ivec
, encryptp
);
2372 * AES draft-raeburn-krb-rijndael-krb-02
2375 void KRB5_LIB_FUNCTION
2376 _krb5_aes_cts_encrypt(const unsigned char *in
, unsigned char *out
,
2377 size_t len
, const void *aes_key
,
2378 unsigned char *ivec
, const int encryptp
)
2380 unsigned char tmp
[AES_BLOCK_SIZE
];
2381 const AES_KEY
*key
= aes_key
; /* XXX remove this when we always have AES */
2385 * In the framework of kerberos, the length can never be shorter
2386 * then at least one blocksize.
2391 while(len
> AES_BLOCK_SIZE
) {
2392 for (i
= 0; i
< AES_BLOCK_SIZE
; i
++)
2393 tmp
[i
] = in
[i
] ^ ivec
[i
];
2394 AES_encrypt(tmp
, out
, key
);
2395 memcpy(ivec
, out
, AES_BLOCK_SIZE
);
2396 len
-= AES_BLOCK_SIZE
;
2397 in
+= AES_BLOCK_SIZE
;
2398 out
+= AES_BLOCK_SIZE
;
2401 for (i
= 0; i
< len
; i
++)
2402 tmp
[i
] = in
[i
] ^ ivec
[i
];
2403 for (; i
< AES_BLOCK_SIZE
; i
++)
2404 tmp
[i
] = 0 ^ ivec
[i
];
2406 AES_encrypt(tmp
, out
- AES_BLOCK_SIZE
, key
);
2408 memcpy(out
, ivec
, len
);
2409 memcpy(ivec
, out
- AES_BLOCK_SIZE
, AES_BLOCK_SIZE
);
2412 unsigned char tmp2
[AES_BLOCK_SIZE
];
2413 unsigned char tmp3
[AES_BLOCK_SIZE
];
2415 while(len
> AES_BLOCK_SIZE
* 2) {
2416 memcpy(tmp
, in
, AES_BLOCK_SIZE
);
2417 AES_decrypt(in
, out
, key
);
2418 for (i
= 0; i
< AES_BLOCK_SIZE
; i
++)
2420 memcpy(ivec
, tmp
, AES_BLOCK_SIZE
);
2421 len
-= AES_BLOCK_SIZE
;
2422 in
+= AES_BLOCK_SIZE
;
2423 out
+= AES_BLOCK_SIZE
;
2426 len
-= AES_BLOCK_SIZE
;
2428 memcpy(tmp
, in
, AES_BLOCK_SIZE
); /* save last iv */
2429 AES_decrypt(in
, tmp2
, key
);
2431 memcpy(tmp3
, in
+ AES_BLOCK_SIZE
, len
);
2432 memcpy(tmp3
+ len
, tmp2
+ len
, AES_BLOCK_SIZE
- len
); /* xor 0 */
2434 for (i
= 0; i
< len
; i
++)
2435 out
[i
+ AES_BLOCK_SIZE
] = tmp2
[i
] ^ tmp3
[i
];
2437 AES_decrypt(tmp3
, out
, key
);
2438 for (i
= 0; i
< AES_BLOCK_SIZE
; i
++)
2440 memcpy(ivec
, tmp
, AES_BLOCK_SIZE
);
2444 static krb5_error_code
2445 AES_CTS_encrypt(krb5_context context
,
2446 struct key_data
*key
,
2449 krb5_boolean encryptp
,
2453 struct krb5_aes_schedule
*aeskey
= key
->schedule
->data
;
2454 char local_ivec
[AES_BLOCK_SIZE
];
2462 if (len
< AES_BLOCK_SIZE
)
2463 krb5_abortx(context
, "invalid use of AES_CTS_encrypt");
2464 if (len
== AES_BLOCK_SIZE
) {
2466 AES_encrypt(data
, data
, k
);
2468 AES_decrypt(data
, data
, k
);
2471 memset(local_ivec
, 0, sizeof(local_ivec
));
2474 _krb5_aes_cts_encrypt(data
, data
, len
, k
, ivec
, encryptp
);
2480 static krb5_error_code
2481 AES_CBC_encrypt(krb5_context context
,
2482 struct key_data
*key
,
2485 krb5_boolean encryptp
,
2489 struct krb5_aes_schedule
*aeskey
= key
->schedule
->data
;
2490 char local_ivec
[AES_BLOCK_SIZE
];
2500 memset(local_ivec
, 0, sizeof(local_ivec
));
2502 AES_cbc_encrypt(data
, data
, len
, k
, ivec
, encryptp
);
2510 static krb5_error_code
2511 RC2_CBC_encrypt(krb5_context context
,
2512 struct key_data
*key
,
2515 krb5_boolean encryptp
,
2519 unsigned char local_ivec
[8];
2520 RC2_KEY
*s
= key
->schedule
->data
;
2523 memset(local_ivec
, 0, sizeof(local_ivec
));
2525 RC2_cbc_encrypt(data
, data
, len
, s
, ivec
, encryptp
);
2530 * section 6 of draft-brezak-win2k-krb-rc4-hmac-03
2532 * warning: not for small children
2535 static krb5_error_code
2536 ARCFOUR_subencrypt(krb5_context context
,
2537 struct key_data
*key
,
2543 struct checksum_type
*c
= _find_checksum (CKSUMTYPE_RSA_MD5
);
2544 Checksum k1_c
, k2_c
, k3_c
, cksum
;
2549 unsigned char *cdata
= data
;
2550 unsigned char k1_c_data
[16], k2_c_data
[16], k3_c_data
[16];
2551 krb5_error_code ret
;
2553 t
[0] = (usage
>> 0) & 0xFF;
2554 t
[1] = (usage
>> 8) & 0xFF;
2555 t
[2] = (usage
>> 16) & 0xFF;
2556 t
[3] = (usage
>> 24) & 0xFF;
2558 k1_c
.checksum
.length
= sizeof(k1_c_data
);
2559 k1_c
.checksum
.data
= k1_c_data
;
2561 ret
= hmac(NULL
, c
, t
, sizeof(t
), 0, key
, &k1_c
);
2563 krb5_abortx(context
, "hmac failed");
2565 memcpy (k2_c_data
, k1_c_data
, sizeof(k1_c_data
));
2567 k2_c
.checksum
.length
= sizeof(k2_c_data
);
2568 k2_c
.checksum
.data
= k2_c_data
;
2571 kb
.keyvalue
= k2_c
.checksum
;
2573 cksum
.checksum
.length
= 16;
2574 cksum
.checksum
.data
= data
;
2576 ret
= hmac(NULL
, c
, cdata
+ 16, len
- 16, 0, &ke
, &cksum
);
2578 krb5_abortx(context
, "hmac failed");
2581 kb
.keyvalue
= k1_c
.checksum
;
2583 k3_c
.checksum
.length
= sizeof(k3_c_data
);
2584 k3_c
.checksum
.data
= k3_c_data
;
2586 ret
= hmac(NULL
, c
, data
, 16, 0, &ke
, &k3_c
);
2588 krb5_abortx(context
, "hmac failed");
2590 RC4_set_key (&rc4_key
, k3_c
.checksum
.length
, k3_c
.checksum
.data
);
2591 RC4 (&rc4_key
, len
- 16, cdata
+ 16, cdata
+ 16);
2592 memset (k1_c_data
, 0, sizeof(k1_c_data
));
2593 memset (k2_c_data
, 0, sizeof(k2_c_data
));
2594 memset (k3_c_data
, 0, sizeof(k3_c_data
));
2598 static krb5_error_code
2599 ARCFOUR_subdecrypt(krb5_context context
,
2600 struct key_data
*key
,
2606 struct checksum_type
*c
= _find_checksum (CKSUMTYPE_RSA_MD5
);
2607 Checksum k1_c
, k2_c
, k3_c
, cksum
;
2612 unsigned char *cdata
= data
;
2613 unsigned char k1_c_data
[16], k2_c_data
[16], k3_c_data
[16];
2614 unsigned char cksum_data
[16];
2615 krb5_error_code ret
;
2617 t
[0] = (usage
>> 0) & 0xFF;
2618 t
[1] = (usage
>> 8) & 0xFF;
2619 t
[2] = (usage
>> 16) & 0xFF;
2620 t
[3] = (usage
>> 24) & 0xFF;
2622 k1_c
.checksum
.length
= sizeof(k1_c_data
);
2623 k1_c
.checksum
.data
= k1_c_data
;
2625 ret
= hmac(NULL
, c
, t
, sizeof(t
), 0, key
, &k1_c
);
2627 krb5_abortx(context
, "hmac failed");
2629 memcpy (k2_c_data
, k1_c_data
, sizeof(k1_c_data
));
2631 k2_c
.checksum
.length
= sizeof(k2_c_data
);
2632 k2_c
.checksum
.data
= k2_c_data
;
2635 kb
.keyvalue
= k1_c
.checksum
;
2637 k3_c
.checksum
.length
= sizeof(k3_c_data
);
2638 k3_c
.checksum
.data
= k3_c_data
;
2640 ret
= hmac(NULL
, c
, cdata
, 16, 0, &ke
, &k3_c
);
2642 krb5_abortx(context
, "hmac failed");
2644 RC4_set_key (&rc4_key
, k3_c
.checksum
.length
, k3_c
.checksum
.data
);
2645 RC4 (&rc4_key
, len
- 16, cdata
+ 16, cdata
+ 16);
2648 kb
.keyvalue
= k2_c
.checksum
;
2650 cksum
.checksum
.length
= 16;
2651 cksum
.checksum
.data
= cksum_data
;
2653 ret
= hmac(NULL
, c
, cdata
+ 16, len
- 16, 0, &ke
, &cksum
);
2655 krb5_abortx(context
, "hmac failed");
2657 memset (k1_c_data
, 0, sizeof(k1_c_data
));
2658 memset (k2_c_data
, 0, sizeof(k2_c_data
));
2659 memset (k3_c_data
, 0, sizeof(k3_c_data
));
2661 if (memcmp (cksum
.checksum
.data
, data
, 16) != 0) {
2662 krb5_clear_error_string (context
);
2663 return KRB5KRB_AP_ERR_BAD_INTEGRITY
;
2670 * convert the usage numbers used in
2671 * draft-ietf-cat-kerb-key-derivation-00.txt to the ones in
2672 * draft-brezak-win2k-krb-rc4-hmac-04.txt
2675 static krb5_error_code
2676 usage2arcfour (krb5_context context
, unsigned *usage
)
2679 case KRB5_KU_AS_REP_ENC_PART
: /* 3 */
2680 case KRB5_KU_TGS_REP_ENC_PART_SUB_KEY
: /* 9 */
2683 case KRB5_KU_USAGE_SEAL
: /* 22 */
2686 case KRB5_KU_USAGE_SIGN
: /* 23 */
2689 case KRB5_KU_USAGE_SEQ
: /* 24 */
2697 static krb5_error_code
2698 ARCFOUR_encrypt(krb5_context context
,
2699 struct key_data
*key
,
2702 krb5_boolean encryptp
,
2706 krb5_error_code ret
;
2707 unsigned keyusage
= usage
;
2709 if((ret
= usage2arcfour (context
, &keyusage
)) != 0)
2713 return ARCFOUR_subencrypt (context
, key
, data
, len
, keyusage
, ivec
);
2715 return ARCFOUR_subdecrypt (context
, key
, data
, len
, keyusage
, ivec
);
2720 * these should currently be in reverse preference order.
2721 * (only relevant for !F_PSEUDO) */
2723 static struct encryption_type enctype_null
= {
2736 static struct encryption_type enctype_des_cbc_crc
= {
2747 DES_CBC_encrypt_key_ivec
,
2749 static struct encryption_type enctype_des_cbc_md4
= {
2758 &checksum_rsa_md4_des
,
2760 DES_CBC_encrypt_null_ivec
,
2762 static struct encryption_type enctype_des_cbc_md5
= {
2771 &checksum_rsa_md5_des
,
2773 DES_CBC_encrypt_null_ivec
,
2775 static struct encryption_type enctype_arcfour_hmac_md5
= {
2776 ETYPE_ARCFOUR_HMAC_MD5
,
2788 static struct encryption_type enctype_des3_cbc_md5
= {
2797 &checksum_rsa_md5_des3
,
2801 static struct encryption_type enctype_des3_cbc_sha1
= {
2802 ETYPE_DES3_CBC_SHA1
,
2808 &keytype_des3_derived
,
2810 &checksum_hmac_sha1_des3
,
2814 static struct encryption_type enctype_old_des3_cbc_sha1
= {
2815 ETYPE_OLD_DES3_CBC_SHA1
,
2816 "old-des3-cbc-sha1",
2823 &checksum_hmac_sha1_des3
,
2827 static struct encryption_type enctype_aes128_cts_hmac_sha1
= {
2828 ETYPE_AES128_CTS_HMAC_SHA1_96
,
2829 "aes128-cts-hmac-sha1-96",
2836 &checksum_hmac_sha1_aes128
,
2840 static struct encryption_type enctype_aes256_cts_hmac_sha1
= {
2841 ETYPE_AES256_CTS_HMAC_SHA1_96
,
2842 "aes256-cts-hmac-sha1-96",
2849 &checksum_hmac_sha1_aes256
,
2853 static unsigned aes_128_cbc_num
[] = { 2, 16, 840, 1, 101, 3, 4, 1, 2 };
2854 static heim_oid aes_128_cbc_oid
= kcrypto_oid_enc(aes_128_cbc_num
);
2855 static struct encryption_type enctype_aes128_cbc_none
= {
2856 ETYPE_AES128_CBC_NONE
,
2868 static unsigned aes_192_cbc_num
[] = { 2, 16, 840, 1, 101, 3, 4, 1, 22 };
2869 static heim_oid aes_192_cbc_oid
= kcrypto_oid_enc(aes_192_cbc_num
);
2870 static struct encryption_type enctype_aes192_cbc_none
= {
2871 ETYPE_AES192_CBC_NONE
,
2883 static unsigned aes_256_cbc_num
[] = { 2, 16, 840, 1, 101, 3, 4, 1, 42 };
2884 static heim_oid aes_256_cbc_oid
= kcrypto_oid_enc(aes_256_cbc_num
);
2885 static struct encryption_type enctype_aes256_cbc_none
= {
2886 ETYPE_AES256_CBC_NONE
,
2898 static struct encryption_type enctype_des_cbc_none
= {
2909 DES_CBC_encrypt_null_ivec
,
2911 static struct encryption_type enctype_des_cfb64_none
= {
2912 ETYPE_DES_CFB64_NONE
,
2922 DES_CFB64_encrypt_null_ivec
,
2924 static struct encryption_type enctype_des_pcbc_none
= {
2925 ETYPE_DES_PCBC_NONE
,
2935 DES_PCBC_encrypt_key_ivec
,
2937 static unsigned des_ede3_cbc_num
[] = { 1, 2, 840, 113549, 3, 7 };
2938 static heim_oid des_ede3_cbc_oid
= kcrypto_oid_enc(des_ede3_cbc_num
);
2939 static struct encryption_type enctype_des3_cbc_none_cms
= {
2940 ETYPE_DES3_CBC_NONE_CMS
,
2941 "des3-cbc-none-cms",
2946 &keytype_des3_derived
,
2952 static struct encryption_type enctype_des3_cbc_none
= {
2953 ETYPE_DES3_CBC_NONE
,
2959 &keytype_des3_derived
,
2965 static unsigned rc2CBC_num
[] = { 1, 2, 840, 113549, 3, 2 };
2966 static heim_oid rc2CBC_oid
= kcrypto_oid_enc(rc2CBC_num
);
2967 static struct encryption_type enctype_rc2_cbc_none
= {
2981 static struct encryption_type
*etypes
[] = {
2983 &enctype_des_cbc_crc
,
2984 &enctype_des_cbc_md4
,
2985 &enctype_des_cbc_md5
,
2986 &enctype_arcfour_hmac_md5
,
2987 &enctype_des3_cbc_md5
,
2988 &enctype_des3_cbc_sha1
,
2989 &enctype_old_des3_cbc_sha1
,
2990 &enctype_aes128_cts_hmac_sha1
,
2991 &enctype_aes256_cts_hmac_sha1
,
2992 &enctype_aes128_cbc_none
,
2993 &enctype_aes192_cbc_none
,
2994 &enctype_aes256_cbc_none
,
2995 &enctype_des_cbc_none
,
2996 &enctype_des_cfb64_none
,
2997 &enctype_des_pcbc_none
,
2998 &enctype_des3_cbc_none
,
2999 &enctype_des3_cbc_none_cms
,
3000 &enctype_rc2_cbc_none
3003 static unsigned num_etypes
= sizeof(etypes
) / sizeof(etypes
[0]);
3006 static struct encryption_type
*
3007 _find_enctype(krb5_enctype type
)
3010 for(i
= 0; i
< num_etypes
; i
++)
3011 if(etypes
[i
]->type
== type
)
3017 krb5_error_code KRB5_LIB_FUNCTION
3018 krb5_enctype_to_string(krb5_context context
,
3022 struct encryption_type
*e
;
3023 e
= _find_enctype(etype
);
3025 krb5_set_error_string (context
, "encryption type %d not supported",
3027 return KRB5_PROG_ETYPE_NOSUPP
;
3029 *string
= strdup(e
->name
);
3030 if(*string
== NULL
) {
3031 krb5_set_error_string(context
, "malloc: out of memory");
3037 krb5_error_code KRB5_LIB_FUNCTION
3038 krb5_string_to_enctype(krb5_context context
,
3040 krb5_enctype
*etype
)
3043 for(i
= 0; i
< num_etypes
; i
++)
3044 if(strcasecmp(etypes
[i
]->name
, string
) == 0){
3045 *etype
= etypes
[i
]->type
;
3048 krb5_set_error_string (context
, "encryption type %s not supported",
3050 return KRB5_PROG_ETYPE_NOSUPP
;
3053 krb5_error_code KRB5_LIB_FUNCTION
3054 krb5_enctype_to_oid(krb5_context context
,
3058 struct encryption_type
*et
= _find_enctype(etype
);
3060 krb5_set_error_string (context
, "encryption type %d not supported",
3062 return KRB5_PROG_ETYPE_NOSUPP
;
3064 if(et
->oid
== NULL
) {
3065 krb5_set_error_string (context
, "%s have not oid", et
->name
);
3066 return KRB5_PROG_ETYPE_NOSUPP
;
3068 krb5_clear_error_string(context
);
3069 return copy_oid(et
->oid
, oid
);
3072 krb5_error_code KRB5_LIB_FUNCTION
3073 _krb5_oid_to_enctype(krb5_context context
,
3074 const heim_oid
*oid
,
3075 krb5_enctype
*etype
)
3078 for(i
= 0; i
< num_etypes
; i
++) {
3079 if(etypes
[i
]->oid
&& heim_oid_cmp(etypes
[i
]->oid
, oid
) == 0) {
3080 *etype
= etypes
[i
]->type
;
3084 krb5_set_error_string(context
, "enctype for oid not supported");
3085 return KRB5_PROG_ETYPE_NOSUPP
;
3088 krb5_error_code KRB5_LIB_FUNCTION
3089 krb5_enctype_to_keytype(krb5_context context
,
3091 krb5_keytype
*keytype
)
3093 struct encryption_type
*e
= _find_enctype(etype
);
3095 krb5_set_error_string (context
, "encryption type %d not supported",
3097 return KRB5_PROG_ETYPE_NOSUPP
;
3099 *keytype
= e
->keytype
->type
; /* XXX */
3104 krb5_error_code KRB5_LIB_FUNCTION
3105 krb5_keytype_to_enctype(krb5_context context
,
3106 krb5_keytype keytype
,
3107 krb5_enctype
*etype
)
3109 struct key_type
*kt
= _find_keytype(keytype
);
3110 krb5_warnx(context
, "krb5_keytype_to_enctype(%u)", keytype
);
3112 return KRB5_PROG_KEYTYPE_NOSUPP
;
3113 *etype
= kt
->best_etype
;
3118 krb5_error_code KRB5_LIB_FUNCTION
3119 krb5_keytype_to_enctypes (krb5_context context
,
3120 krb5_keytype keytype
,
3128 for (i
= num_etypes
- 1; i
>= 0; --i
) {
3129 if (etypes
[i
]->keytype
->type
== keytype
3130 && !(etypes
[i
]->flags
& F_PSEUDO
))
3133 ret
= malloc(n
* sizeof(*ret
));
3134 if (ret
== NULL
&& n
!= 0) {
3135 krb5_set_error_string(context
, "malloc: out of memory");
3139 for (i
= num_etypes
- 1; i
>= 0; --i
) {
3140 if (etypes
[i
]->keytype
->type
== keytype
3141 && !(etypes
[i
]->flags
& F_PSEUDO
))
3142 ret
[n
++] = etypes
[i
]->type
;
3150 * First take the configured list of etypes for `keytype' if available,
3151 * else, do `krb5_keytype_to_enctypes'.
3154 krb5_error_code KRB5_LIB_FUNCTION
3155 krb5_keytype_to_enctypes_default (krb5_context context
,
3156 krb5_keytype keytype
,
3163 if (keytype
!= KEYTYPE_DES
|| context
->etypes_des
== NULL
)
3164 return krb5_keytype_to_enctypes (context
, keytype
, len
, val
);
3166 for (n
= 0; context
->etypes_des
[n
]; ++n
)
3168 ret
= malloc (n
* sizeof(*ret
));
3169 if (ret
== NULL
&& n
!= 0) {
3170 krb5_set_error_string(context
, "malloc: out of memory");
3173 for (i
= 0; i
< n
; ++i
)
3174 ret
[i
] = context
->etypes_des
[i
];
3180 krb5_error_code KRB5_LIB_FUNCTION
3181 krb5_enctype_valid(krb5_context context
,
3184 struct encryption_type
*e
= _find_enctype(etype
);
3186 krb5_set_error_string (context
, "encryption type %d not supported",
3188 return KRB5_PROG_ETYPE_NOSUPP
;
3190 if (e
->flags
& F_DISABLED
) {
3191 krb5_set_error_string (context
, "encryption type %s is disabled",
3193 return KRB5_PROG_ETYPE_NOSUPP
;
3198 krb5_error_code KRB5_LIB_FUNCTION
3199 krb5_cksumtype_valid(krb5_context context
,
3200 krb5_cksumtype ctype
)
3202 struct checksum_type
*c
= _find_checksum(ctype
);
3204 krb5_set_error_string (context
, "checksum type %d not supported",
3206 return KRB5_PROG_SUMTYPE_NOSUPP
;
3208 if (c
->flags
& F_DISABLED
) {
3209 krb5_set_error_string (context
, "checksum type %s is disabled",
3211 return KRB5_PROG_SUMTYPE_NOSUPP
;
3217 /* if two enctypes have compatible keys */
3218 krb5_boolean KRB5_LIB_FUNCTION
3219 krb5_enctypes_compatible_keys(krb5_context context
,
3220 krb5_enctype etype1
,
3221 krb5_enctype etype2
)
3223 struct encryption_type
*e1
= _find_enctype(etype1
);
3224 struct encryption_type
*e2
= _find_enctype(etype2
);
3225 return e1
!= NULL
&& e2
!= NULL
&& e1
->keytype
== e2
->keytype
;
3229 derived_crypto(krb5_context context
,
3232 return (crypto
->et
->flags
& F_DERIVED
) != 0;
3236 special_crypto(krb5_context context
,
3239 return (crypto
->et
->flags
& F_SPECIAL
) != 0;
3242 #define CHECKSUMSIZE(C) ((C)->checksumsize)
3243 #define CHECKSUMTYPE(C) ((C)->type)
3245 static krb5_error_code
3246 encrypt_internal_derived(krb5_context context
,
3254 size_t sz
, block_sz
, checksum_sz
, total_sz
;
3256 unsigned char *p
, *q
;
3257 krb5_error_code ret
;
3258 struct key_data
*dkey
;
3259 const struct encryption_type
*et
= crypto
->et
;
3261 checksum_sz
= CHECKSUMSIZE(et
->keyed_checksum
);
3263 sz
= et
->confoundersize
+ len
;
3264 block_sz
= (sz
+ et
->padsize
- 1) &~ (et
->padsize
- 1); /* pad */
3265 total_sz
= block_sz
+ checksum_sz
;
3266 p
= calloc(1, total_sz
);
3268 krb5_set_error_string(context
, "malloc: out of memory");
3273 krb5_generate_random_block(q
, et
->confoundersize
); /* XXX */
3274 q
+= et
->confoundersize
;
3275 memcpy(q
, data
, len
);
3277 ret
= create_checksum(context
,
3280 INTEGRITY_USAGE(usage
),
3284 if(ret
== 0 && cksum
.checksum
.length
!= checksum_sz
) {
3285 free_Checksum (&cksum
);
3286 krb5_clear_error_string (context
);
3287 ret
= KRB5_CRYPTO_INTERNAL
;
3291 memcpy(p
+ block_sz
, cksum
.checksum
.data
, cksum
.checksum
.length
);
3292 free_Checksum (&cksum
);
3293 ret
= _get_derived_key(context
, crypto
, ENCRYPTION_USAGE(usage
), &dkey
);
3296 ret
= _key_schedule(context
, dkey
, crypto
->params
);
3300 krb5_crypto_debug(context
, 1, block_sz
, dkey
->key
);
3302 ret
= (*et
->encrypt
)(context
, dkey
, p
, block_sz
, 1, usage
, ivec
);
3306 result
->length
= total_sz
;
3309 memset(p
, 0, total_sz
);
3315 static krb5_error_code
3316 encrypt_internal(krb5_context context
,
3323 size_t sz
, block_sz
, checksum_sz
, padsize
= 0;
3325 unsigned char *p
, *q
;
3326 krb5_error_code ret
;
3327 const struct encryption_type
*et
= crypto
->et
;
3329 checksum_sz
= CHECKSUMSIZE(et
->checksum
);
3331 sz
= et
->confoundersize
+ checksum_sz
+ len
;
3332 block_sz
= (sz
+ et
->padsize
- 1) &~ (et
->padsize
- 1); /* pad */
3333 if ((et
->flags
& F_PADCMS
) && et
->padsize
!= 1) {
3334 padsize
= et
->padsize
- (sz
% et
->padsize
);
3335 if (padsize
== et
->padsize
)
3336 block_sz
+= et
->padsize
;
3338 p
= calloc(1, block_sz
);
3340 krb5_set_error_string(context
, "malloc: out of memory");
3345 krb5_generate_random_block(q
, et
->confoundersize
); /* XXX */
3346 q
+= et
->confoundersize
;
3347 memset(q
, 0, checksum_sz
);
3349 memcpy(q
, data
, len
);
3351 ret
= create_checksum(context
,
3358 if(ret
== 0 && cksum
.checksum
.length
!= checksum_sz
) {
3359 krb5_clear_error_string (context
);
3360 free_Checksum(&cksum
);
3361 ret
= KRB5_CRYPTO_INTERNAL
;
3365 memcpy(p
+ et
->confoundersize
, cksum
.checksum
.data
, cksum
.checksum
.length
);
3366 free_Checksum(&cksum
);
3367 ret
= _key_schedule(context
, &crypto
->key
, crypto
->params
);
3370 if (et
->flags
& F_PADCMS
) {
3372 q
= p
+ len
+ checksum_sz
+ et
->confoundersize
;
3373 for (i
= 0; i
< padsize
; i
++)
3377 krb5_crypto_debug(context
, 1, block_sz
, crypto
->key
.key
);
3379 ret
= (*et
->encrypt
)(context
, &crypto
->key
, p
, block_sz
, 1, 0, ivec
);
3381 memset(p
, 0, block_sz
);
3386 result
->length
= block_sz
;
3389 memset(p
, 0, block_sz
);
3394 static krb5_error_code
3395 encrypt_internal_special(krb5_context context
,
3403 struct encryption_type
*et
= crypto
->et
;
3404 size_t cksum_sz
= CHECKSUMSIZE(et
->checksum
);
3405 size_t sz
= len
+ cksum_sz
+ et
->confoundersize
;
3407 krb5_error_code ret
;
3411 krb5_set_error_string(context
, "malloc: out of memory");
3415 memset (p
, 0, cksum_sz
);
3417 krb5_generate_random_block(p
, et
->confoundersize
);
3418 p
+= et
->confoundersize
;
3419 memcpy (p
, data
, len
);
3420 ret
= (*et
->encrypt
)(context
, &crypto
->key
, tmp
, sz
, TRUE
, usage
, ivec
);
3427 result
->length
= sz
;
3431 static krb5_error_code
3432 decrypt_internal_derived(krb5_context context
,
3443 krb5_error_code ret
;
3444 struct key_data
*dkey
;
3445 struct encryption_type
*et
= crypto
->et
;
3448 checksum_sz
= CHECKSUMSIZE(et
->keyed_checksum
);
3449 if (len
< checksum_sz
) {
3450 krb5_clear_error_string (context
);
3451 return EINVAL
; /* XXX - better error code? */
3454 if (((len
- checksum_sz
) % et
->padsize
) != 0) {
3455 krb5_clear_error_string(context
);
3456 return KRB5_BAD_MSIZE
;
3460 if(len
!= 0 && p
== NULL
) {
3461 krb5_set_error_string(context
, "malloc: out of memory");
3464 memcpy(p
, data
, len
);
3468 ret
= _get_derived_key(context
, crypto
, ENCRYPTION_USAGE(usage
), &dkey
);
3473 ret
= _key_schedule(context
, dkey
, crypto
->params
);
3479 krb5_crypto_debug(context
, 0, len
, dkey
->key
);
3481 ret
= (*et
->encrypt
)(context
, dkey
, p
, len
, 0, usage
, ivec
);
3487 cksum
.checksum
.data
= p
+ len
;
3488 cksum
.checksum
.length
= checksum_sz
;
3489 cksum
.cksumtype
= CHECKSUMTYPE(et
->keyed_checksum
);
3491 ret
= verify_checksum(context
,
3493 INTEGRITY_USAGE(usage
),
3501 l
= len
- et
->confoundersize
;
3502 memmove(p
, p
+ et
->confoundersize
, l
);
3503 result
->data
= realloc(p
, l
);
3504 if(result
->data
== NULL
) {
3506 krb5_set_error_string(context
, "malloc: out of memory");
3513 static krb5_error_code
3514 decrypt_internal(krb5_context context
,
3521 krb5_error_code ret
;
3524 size_t checksum_sz
, l
;
3525 struct encryption_type
*et
= crypto
->et
;
3527 if ((len
% et
->padsize
) != 0) {
3528 krb5_clear_error_string(context
);
3529 return KRB5_BAD_MSIZE
;
3532 checksum_sz
= CHECKSUMSIZE(et
->checksum
);
3534 if(len
!= 0 && p
== NULL
) {
3535 krb5_set_error_string(context
, "malloc: out of memory");
3538 memcpy(p
, data
, len
);
3540 ret
= _key_schedule(context
, &crypto
->key
, crypto
->params
);
3546 krb5_crypto_debug(context
, 0, len
, crypto
->key
.key
);
3548 ret
= (*et
->encrypt
)(context
, &crypto
->key
, p
, len
, 0, 0, ivec
);
3553 ret
= krb5_data_copy(&cksum
.checksum
, p
+ et
->confoundersize
, checksum_sz
);
3558 memset(p
+ et
->confoundersize
, 0, checksum_sz
);
3559 cksum
.cksumtype
= CHECKSUMTYPE(et
->checksum
);
3560 ret
= verify_checksum(context
, NULL
, 0, p
, len
, &cksum
);
3561 free_Checksum(&cksum
);
3566 l
= len
- et
->confoundersize
- checksum_sz
;
3567 memmove(p
, p
+ et
->confoundersize
+ checksum_sz
, l
);
3568 result
->data
= realloc(p
, l
);
3569 if(result
->data
== NULL
) {
3571 krb5_set_error_string(context
, "malloc: out of memory");
3578 static krb5_error_code
3579 decrypt_internal_special(krb5_context context
,
3587 struct encryption_type
*et
= crypto
->et
;
3588 size_t cksum_sz
= CHECKSUMSIZE(et
->checksum
);
3589 size_t sz
= len
- cksum_sz
- et
->confoundersize
;
3591 krb5_error_code ret
;
3593 if ((len
% et
->padsize
) != 0) {
3594 krb5_clear_error_string(context
);
3595 return KRB5_BAD_MSIZE
;
3600 krb5_set_error_string(context
, "malloc: out of memory");
3603 memcpy(p
, data
, len
);
3605 ret
= (*et
->encrypt
)(context
, &crypto
->key
, p
, len
, FALSE
, usage
, ivec
);
3611 memmove (p
, p
+ cksum_sz
+ et
->confoundersize
, sz
);
3612 result
->data
= realloc(p
, sz
);
3613 if(result
->data
== NULL
) {
3615 krb5_set_error_string(context
, "malloc: out of memory");
3618 result
->length
= sz
;
3623 krb5_error_code KRB5_LIB_FUNCTION
3624 krb5_encrypt_ivec(krb5_context context
,
3632 if(derived_crypto(context
, crypto
))
3633 return encrypt_internal_derived(context
, crypto
, usage
,
3634 data
, len
, result
, ivec
);
3635 else if (special_crypto(context
, crypto
))
3636 return encrypt_internal_special (context
, crypto
, usage
,
3637 data
, len
, result
, ivec
);
3639 return encrypt_internal(context
, crypto
, data
, len
, result
, ivec
);
3642 krb5_error_code KRB5_LIB_FUNCTION
3643 krb5_encrypt(krb5_context context
,
3650 return krb5_encrypt_ivec(context
, crypto
, usage
, data
, len
, result
, NULL
);
3653 krb5_error_code KRB5_LIB_FUNCTION
3654 krb5_encrypt_EncryptedData(krb5_context context
,
3660 EncryptedData
*result
)
3662 result
->etype
= CRYPTO_ETYPE(crypto
);
3664 ALLOC(result
->kvno
, 1);
3665 *result
->kvno
= kvno
;
3667 result
->kvno
= NULL
;
3668 return krb5_encrypt(context
, crypto
, usage
, data
, len
, &result
->cipher
);
3671 krb5_error_code KRB5_LIB_FUNCTION
3672 krb5_decrypt_ivec(krb5_context context
,
3680 if(derived_crypto(context
, crypto
))
3681 return decrypt_internal_derived(context
, crypto
, usage
,
3682 data
, len
, result
, ivec
);
3683 else if (special_crypto (context
, crypto
))
3684 return decrypt_internal_special(context
, crypto
, usage
,
3685 data
, len
, result
, ivec
);
3687 return decrypt_internal(context
, crypto
, data
, len
, result
, ivec
);
3690 krb5_error_code KRB5_LIB_FUNCTION
3691 krb5_decrypt(krb5_context context
,
3698 return krb5_decrypt_ivec (context
, crypto
, usage
, data
, len
, result
,
3702 krb5_error_code KRB5_LIB_FUNCTION
3703 krb5_decrypt_EncryptedData(krb5_context context
,
3706 const EncryptedData
*e
,
3709 return krb5_decrypt(context
, crypto
, usage
,
3710 e
->cipher
.data
, e
->cipher
.length
, result
);
3713 /************************************************************
3715 ************************************************************/
3718 #include <openssl/rand.h>
3720 /* From openssl/crypto/rand/rand_lcl.h */
3721 #define ENTROPY_NEEDED 20
3723 seed_something(void)
3725 char buf
[1024], seedfile
[256];
3727 /* If there is a seed file, load it. But such a file cannot be trusted,
3728 so use 0 for the entropy estimate */
3729 if (RAND_file_name(seedfile
, sizeof(seedfile
))) {
3731 fd
= open(seedfile
, O_RDONLY
);
3734 ret
= read(fd
, buf
, sizeof(buf
));
3736 RAND_add(buf
, ret
, 0.0);
3743 /* Calling RAND_status() will try to use /dev/urandom if it exists so
3744 we do not have to deal with it. */
3745 if (RAND_status() != 1) {
3746 krb5_context context
;
3750 if (!krb5_init_context(&context
)) {
3751 p
= krb5_config_get_string(context
, NULL
, "libdefaults",
3752 "egd_socket", NULL
);
3754 RAND_egd_bytes(p
, ENTROPY_NEEDED
);
3755 krb5_free_context(context
);
3759 if (RAND_status() == 1) {
3760 /* Update the seed file */
3762 RAND_write_file(seedfile
);
3769 void KRB5_LIB_FUNCTION
3770 krb5_generate_random_block(void *buf
, size_t len
)
3772 static int rng_initialized
= 0;
3774 HEIMDAL_MUTEX_lock(&crypto_mutex
);
3775 if (!rng_initialized
) {
3776 if (seed_something())
3777 krb5_abortx(NULL
, "Fatal: could not seed the random number generator");
3779 rng_initialized
= 1;
3781 HEIMDAL_MUTEX_unlock(&crypto_mutex
);
3782 RAND_bytes(buf
, len
);
3787 void KRB5_LIB_FUNCTION
3788 krb5_generate_random_block(void *buf
, size_t len
)
3790 DES_cblock key
, out
;
3791 static DES_cblock counter
;
3792 static DES_key_schedule schedule
;
3794 static int initialized
= 0;
3796 HEIMDAL_MUTEX_lock(&crypto_mutex
);
3798 DES_new_random_key(&key
);
3799 DES_set_key(&key
, &schedule
);
3800 memset(&key
, 0, sizeof(key
));
3801 DES_new_random_key(&counter
);
3804 HEIMDAL_MUTEX_unlock(&crypto_mutex
);
3806 DES_ecb_encrypt(&counter
, &out
, &schedule
, DES_ENCRYPT
);
3807 for(i
= 7; i
>=0; i
--)
3810 memcpy(buf
, out
, min(len
, sizeof(out
)));
3811 len
-= min(len
, sizeof(out
));
3812 buf
= (char*)buf
+ sizeof(out
);
3818 DES3_postproc(krb5_context context
,
3819 unsigned char *k
, size_t len
, struct key_data
*key
)
3821 DES3_random_to_key(context
, key
->key
, k
, len
);
3823 if (key
->schedule
) {
3824 krb5_free_data(context
, key
->schedule
);
3825 key
->schedule
= NULL
;
3829 static krb5_error_code
3830 derive_key(krb5_context context
,
3831 struct encryption_type
*et
,
3832 struct key_data
*key
,
3833 const void *constant
,
3837 unsigned int nblocks
= 0, i
;
3838 krb5_error_code ret
= 0;
3840 struct key_type
*kt
= et
->keytype
;
3841 /* since RC2 is only the weird crypto alg with parameter and this
3842 * function not defined with work with RC2, this is ok */
3843 ret
= _key_schedule(context
, key
, NULL
);
3846 if(et
->blocksize
* 8 < kt
->bits
||
3847 len
!= et
->blocksize
) {
3848 nblocks
= (kt
->bits
+ et
->blocksize
* 8 - 1) / (et
->blocksize
* 8);
3849 k
= malloc(nblocks
* et
->blocksize
);
3851 krb5_set_error_string(context
, "malloc: out of memory");
3854 _krb5_n_fold(constant
, len
, k
, et
->blocksize
);
3855 for(i
= 0; i
< nblocks
; i
++) {
3857 memcpy(k
+ i
* et
->blocksize
,
3858 k
+ (i
- 1) * et
->blocksize
,
3860 (*et
->encrypt
)(context
, key
, k
+ i
* et
->blocksize
, et
->blocksize
,
3864 /* this case is probably broken, but won't be run anyway */
3865 void *c
= malloc(len
);
3866 size_t res_len
= (kt
->bits
+ 7) / 8;
3868 if(len
!= 0 && c
== NULL
) {
3869 krb5_set_error_string(context
, "malloc: out of memory");
3872 memcpy(c
, constant
, len
);
3873 (*et
->encrypt
)(context
, key
, c
, len
, 1, 0, NULL
);
3874 k
= malloc(res_len
);
3875 if(res_len
!= 0 && k
== NULL
) {
3877 krb5_set_error_string(context
, "malloc: out of memory");
3880 _krb5_n_fold(c
, len
, k
, res_len
);
3884 /* XXX keytype dependent post-processing */
3887 DES3_postproc(context
, k
, nblocks
* et
->blocksize
, key
);
3889 case KEYTYPE_AES128
:
3890 case KEYTYPE_AES256
:
3891 memcpy(key
->key
->keyvalue
.data
, k
, key
->key
->keyvalue
.length
);
3894 krb5_set_error_string(context
,
3895 "derive_key() called with unknown keytype (%u)",
3897 ret
= KRB5_CRYPTO_INTERNAL
;
3900 if (key
->schedule
) {
3901 krb5_free_data(context
, key
->schedule
);
3902 key
->schedule
= NULL
;
3904 memset(k
, 0, nblocks
* et
->blocksize
);
3909 static struct key_data
*
3910 _new_derived_key(krb5_crypto crypto
, unsigned usage
)
3912 struct key_usage
*d
= crypto
->key_usage
;
3913 d
= realloc(d
, (crypto
->num_key_usage
+ 1) * sizeof(*d
));
3916 crypto
->key_usage
= d
;
3917 d
+= crypto
->num_key_usage
++;
3918 memset(d
, 0, sizeof(*d
));
3923 krb5_error_code KRB5_LIB_FUNCTION
3924 krb5_derive_key(krb5_context context
,
3925 const krb5_keyblock
*key
,
3927 const void *constant
,
3928 size_t constant_len
,
3929 krb5_keyblock
**derived_key
)
3931 krb5_error_code ret
;
3932 struct encryption_type
*et
;
3935 et
= _find_enctype (etype
);
3937 krb5_set_error_string(context
, "encryption type %d not supported",
3939 return KRB5_PROG_ETYPE_NOSUPP
;
3942 ret
= krb5_copy_keyblock(context
, key
, derived_key
);
3946 d
.key
= *derived_key
;
3948 ret
= derive_key(context
, et
, &d
, constant
, constant_len
);
3951 ret
= krb5_copy_keyblock(context
, d
.key
, derived_key
);
3955 static krb5_error_code
3956 _get_derived_key(krb5_context context
,
3959 struct key_data
**key
)
3963 unsigned char constant
[5];
3965 for(i
= 0; i
< crypto
->num_key_usage
; i
++)
3966 if(crypto
->key_usage
[i
].usage
== usage
) {
3967 *key
= &crypto
->key_usage
[i
].key
;
3970 d
= _new_derived_key(crypto
, usage
);
3972 krb5_set_error_string(context
, "malloc: out of memory");
3975 krb5_copy_keyblock(context
, crypto
->key
.key
, &d
->key
);
3976 _krb5_put_int(constant
, usage
, 5);
3977 derive_key(context
, crypto
->et
, d
, constant
, sizeof(constant
));
3983 krb5_error_code KRB5_LIB_FUNCTION
3984 krb5_crypto_init(krb5_context context
,
3985 const krb5_keyblock
*key
,
3987 krb5_crypto
*crypto
)
3989 krb5_error_code ret
;
3991 if(*crypto
== NULL
) {
3992 krb5_set_error_string(context
, "malloc: out of memory");
3995 if(etype
== ETYPE_NULL
)
3996 etype
= key
->keytype
;
3997 (*crypto
)->et
= _find_enctype(etype
);
3998 if((*crypto
)->et
== NULL
|| ((*crypto
)->et
->flags
& F_DISABLED
)) {
4001 krb5_set_error_string (context
, "encryption type %d not supported",
4003 return KRB5_PROG_ETYPE_NOSUPP
;
4005 if((*crypto
)->et
->keytype
->minsize
> key
->keyvalue
.length
) {
4008 krb5_set_error_string (context
, "encryption key has bad length");
4009 return KRB5_BAD_KEYSIZE
;
4011 ret
= krb5_copy_keyblock(context
, key
, &(*crypto
)->key
.key
);
4017 (*crypto
)->key
.schedule
= NULL
;
4018 (*crypto
)->num_key_usage
= 0;
4019 (*crypto
)->key_usage
= NULL
;
4020 (*crypto
)->params
= NULL
;
4025 free_key_data(krb5_context context
, struct key_data
*key
)
4027 krb5_free_keyblock(context
, key
->key
);
4029 memset(key
->schedule
->data
, 0, key
->schedule
->length
);
4030 krb5_free_data(context
, key
->schedule
);
4035 free_key_usage(krb5_context context
, struct key_usage
*ku
)
4037 free_key_data(context
, &ku
->key
);
4040 krb5_error_code KRB5_LIB_FUNCTION
4041 krb5_crypto_destroy(krb5_context context
,
4046 for(i
= 0; i
< crypto
->num_key_usage
; i
++)
4047 free_key_usage(context
, &crypto
->key_usage
[i
]);
4048 free(crypto
->key_usage
);
4049 free_key_data(context
, &crypto
->key
);
4050 free(crypto
->params
);
4055 krb5_error_code KRB5_LIB_FUNCTION
4056 krb5_crypto_get_params(krb5_context context
,
4057 const krb5_crypto crypto
,
4058 const krb5_data
*params
,
4061 krb5_error_code (*gp
)(krb5_context
, const krb5_data
*,void **,krb5_data
*);
4062 krb5_error_code ret
;
4064 gp
= crypto
->et
->keytype
->get_params
;
4066 if (crypto
->params
) {
4067 krb5_set_error_string(context
,
4068 "krb5_crypto_get_params called "
4070 return KRB5_PROG_ETYPE_NOSUPP
;
4072 ret
= (*gp
)(context
, params
, &crypto
->params
, ivec
);
4077 ret
= decode_CBCParameter(params
->data
, params
->length
, ivec
, &size
);
4081 if (ivec
->length
< crypto
->et
->blocksize
) {
4082 krb5_data_free(ivec
);
4083 krb5_set_error_string(context
, "%s IV of wrong size",
4085 return ASN1_PARSE_ERROR
;
4090 krb5_error_code KRB5_LIB_FUNCTION
4091 krb5_crypto_set_params(krb5_context context
,
4092 const krb5_crypto crypto
,
4093 const krb5_data
*ivec
,
4096 krb5_error_code (*sp
)(krb5_context
, const void *,
4097 const krb5_data
*, krb5_data
*);
4098 krb5_error_code ret
;
4100 sp
= crypto
->et
->keytype
->set_params
;
4105 ASN1_MALLOC_ENCODE(CBCParameter
, params
->data
, params
->length
,
4109 if (size
!= params
->length
)
4110 krb5_abortx(context
, "Internal asn1 encoder failure");
4113 if (crypto
->params
) {
4114 krb5_set_error_string(context
,
4115 "krb5_crypto_set_params called "
4117 return KRB5_PROG_ETYPE_NOSUPP
;
4119 return (*sp
)(context
, crypto
->params
, ivec
, params
);
4123 krb5_error_code KRB5_LIB_FUNCTION
4124 krb5_crypto_getblocksize(krb5_context context
,
4128 *blocksize
= crypto
->et
->blocksize
;
4132 krb5_error_code KRB5_LIB_FUNCTION
4133 krb5_crypto_getenctype(krb5_context context
,
4135 krb5_enctype
*enctype
)
4137 *enctype
= crypto
->et
->type
;
4141 krb5_error_code KRB5_LIB_FUNCTION
4142 krb5_crypto_getpadsize(krb5_context context
,
4146 *padsize
= crypto
->et
->padsize
;
4150 krb5_error_code KRB5_LIB_FUNCTION
4151 krb5_crypto_getconfoundersize(krb5_context context
,
4153 size_t *confoundersize
)
4155 *confoundersize
= crypto
->et
->confoundersize
;
4159 krb5_error_code KRB5_LIB_FUNCTION
4160 krb5_enctype_disable(krb5_context context
,
4161 krb5_enctype enctype
)
4163 struct encryption_type
*et
= _find_enctype(enctype
);
4166 krb5_set_error_string (context
, "encryption type %d not supported",
4168 return KRB5_PROG_ETYPE_NOSUPP
;
4170 et
->flags
|= F_DISABLED
;
4174 krb5_error_code KRB5_LIB_FUNCTION
4175 krb5_string_to_key_derived(krb5_context context
,
4181 struct encryption_type
*et
= _find_enctype(etype
);
4182 krb5_error_code ret
;
4184 size_t keylen
= et
->keytype
->bits
/ 8;
4188 krb5_set_error_string (context
, "encryption type %d not supported",
4190 return KRB5_PROG_ETYPE_NOSUPP
;
4193 if(kd
.key
== NULL
) {
4194 krb5_set_error_string (context
, "malloc: out of memory");
4197 ret
= krb5_data_alloc(&kd
.key
->keyvalue
, et
->keytype
->size
);
4202 kd
.key
->keytype
= etype
;
4203 tmp
= malloc (keylen
);
4205 krb5_free_keyblock(context
, kd
.key
);
4206 krb5_set_error_string (context
, "malloc: out of memory");
4209 _krb5_n_fold(str
, len
, tmp
, keylen
);
4211 DES3_postproc (context
, tmp
, keylen
, &kd
); /* XXX */
4212 memset(tmp
, 0, keylen
);
4214 ret
= derive_key(context
,
4217 "kerberos", /* XXX well known constant */
4218 strlen("kerberos"));
4219 ret
= krb5_copy_keyblock_contents(context
, kd
.key
, key
);
4220 free_key_data(context
, &kd
);
4225 wrapped_length (krb5_context context
,
4229 struct encryption_type
*et
= crypto
->et
;
4230 size_t padsize
= et
->padsize
;
4231 size_t checksumsize
= CHECKSUMSIZE(et
->checksum
);
4234 res
= et
->confoundersize
+ checksumsize
+ data_len
;
4235 res
= (res
+ padsize
- 1) / padsize
* padsize
;
4240 wrapped_length_dervied (krb5_context context
,
4244 struct encryption_type
*et
= crypto
->et
;
4245 size_t padsize
= et
->padsize
;
4248 res
= et
->confoundersize
+ data_len
;
4249 res
= (res
+ padsize
- 1) / padsize
* padsize
;
4250 if (et
->keyed_checksum
)
4251 res
+= et
->keyed_checksum
->checksumsize
;
4253 res
+= et
->checksum
->checksumsize
;
4258 * Return the size of an encrypted packet of length `data_len'
4262 krb5_get_wrapped_length (krb5_context context
,
4266 if (derived_crypto (context
, crypto
))
4267 return wrapped_length_dervied (context
, crypto
, data_len
);
4269 return wrapped_length (context
, crypto
, data_len
);
4272 krb5_error_code KRB5_LIB_FUNCTION
4273 krb5_random_to_key(krb5_context context
,
4279 krb5_error_code ret
;
4280 struct encryption_type
*et
= _find_enctype(type
);
4282 krb5_set_error_string(context
, "encryption type %d not supported",
4284 return KRB5_PROG_ETYPE_NOSUPP
;
4286 if ((et
->keytype
->bits
+ 7) / 8 > size
) {
4287 krb5_set_error_string(context
, "encryption key %s needs %d bytes "
4288 "of random to make an encryption key out of it",
4289 et
->name
, (int)et
->keytype
->size
);
4290 return KRB5_PROG_ETYPE_NOSUPP
;
4292 ret
= krb5_data_alloc(&key
->keyvalue
, et
->keytype
->size
);
4295 key
->keytype
= type
;
4296 if (et
->keytype
->random_to_key
)
4297 (*et
->keytype
->random_to_key
)(context
, key
, data
, size
);
4299 memcpy(key
->keyvalue
.data
, data
, et
->keytype
->size
);
4305 _krb5_pk_octetstring2key(krb5_context context
,
4309 const heim_octet_string
*c_n
,
4310 const heim_octet_string
*k_n
,
4313 struct encryption_type
*et
= _find_enctype(type
);
4314 krb5_error_code ret
;
4315 size_t keylen
, offset
;
4317 unsigned char counter
;
4318 unsigned char shaoutput
[20];
4321 krb5_set_error_string(context
, "encryption type %d not supported",
4323 return KRB5_PROG_ETYPE_NOSUPP
;
4325 keylen
= (et
->keytype
->bits
+ 7) / 8;
4327 keydata
= malloc(keylen
);
4328 if (keydata
== NULL
) {
4329 krb5_set_error_string(context
, "malloc: out of memory");
4339 SHA1_Update(&m
, &counter
, 1);
4340 SHA1_Update(&m
, dhdata
, dhsize
);
4342 SHA1_Update(&m
, c_n
->data
, c_n
->length
);
4344 SHA1_Update(&m
, k_n
->data
, k_n
->length
);
4345 SHA1_Final(shaoutput
, &m
);
4347 memcpy((unsigned char *)keydata
+ offset
,
4349 min(keylen
- offset
, sizeof(shaoutput
)));
4351 offset
+= sizeof(shaoutput
);
4353 } while(offset
< keylen
);
4354 memset(shaoutput
, 0, sizeof(shaoutput
));
4356 ret
= krb5_random_to_key(context
, type
, keydata
, keylen
, key
);
4357 memset(keydata
, 0, sizeof(keylen
));
4365 static krb5_error_code
4366 krb5_get_keyid(krb5_context context
,
4371 unsigned char tmp
[16];
4374 MD5_Update (&md5
, key
->keyvalue
.data
, key
->keyvalue
.length
);
4375 MD5_Final (tmp
, &md5
);
4376 *keyid
= (tmp
[12] << 24) | (tmp
[13] << 16) | (tmp
[14] << 8) | tmp
[15];
4381 krb5_crypto_debug(krb5_context context
,
4388 krb5_get_keyid(context
, key
, &keyid
);
4389 krb5_enctype_to_string(context
, key
->keytype
, &kt
);
4390 krb5_warnx(context
, "%s %lu bytes with key-id %#x (%s)",
4391 encryptp
? "encrypting" : "decrypting",
4398 #endif /* CRYPTO_DEBUG */
4406 krb5_context context
;
4411 unsigned usage
= ENCRYPTION_USAGE(3);
4412 krb5_error_code ret
;
4414 ret
= krb5_init_context(&context
);
4416 errx (1, "krb5_init_context failed: %d", ret
);
4418 key
.keytype
= ETYPE_NEW_DES3_CBC_SHA1
;
4419 key
.keyvalue
.data
= "\xb3\x85\x58\x94\xd9\xdc\x7c\xc8"
4420 "\x25\xe9\x85\xab\x3e\xb5\xfb\x0e"
4421 "\xc8\xdf\xab\x26\x86\x64\x15\x25";
4422 key
.keyvalue
.length
= 24;
4424 krb5_crypto_init(context
, &key
, 0, &crypto
);
4426 d
= _new_derived_key(crypto
, usage
);
4429 krb5_copy_keyblock(context
, crypto
->key
.key
, &d
->key
);
4430 _krb5_put_int(constant
, usage
, 4);
4431 derive_key(context
, crypto
->et
, d
, constant
, sizeof(constant
));
4435 krb5_context context
;
4439 krb5_error_code ret
;
4442 char *data
= "what do ya want for nothing?";
4444 ret
= krb5_init_context(&context
);
4446 errx (1, "krb5_init_context failed: %d", ret
);
4448 key
.keytype
= ETYPE_NEW_DES3_CBC_SHA1
;
4449 key
.keyvalue
.data
= "Jefe";
4450 /* "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
4451 "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"; */
4452 key
.keyvalue
.length
= 4;
4454 d
= calloc(1, sizeof(*d
));
4457 res
.checksum
.length
= 20;
4458 res
.checksum
.data
= malloc(res
.checksum
.length
);
4459 SP_HMAC_SHA1_checksum(context
, d
, data
, 28, &res
);