2 * Copyright (c) 1997 - 2004 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.73.2.4 2004/03/06 16:38:00 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
;
60 #define CRYPTO_ETYPE(C) ((C)->et->type)
62 /* bits for `flags' below */
63 #define F_KEYED 1 /* checksum is keyed */
64 #define F_CPROOF 2 /* checksum is collision proof */
65 #define F_DERIVED 4 /* uses derived keys */
66 #define F_VARIANT 8 /* uses `variant' keys (6.4.3) */
67 #define F_PSEUDO 16 /* not a real protocol type */
68 #define F_SPECIAL 32 /* backwards */
73 krb5_error_code (*string_to_key
)(krb5_context
, krb5_enctype
, krb5_data
,
74 krb5_salt
, krb5_data
, krb5_keyblock
*);
78 krb5_keytype type
; /* XXX */
84 krb5_enctype best_etype
;
86 void (*random_key
)(krb5_context
, krb5_keyblock
*);
87 void (*schedule
)(krb5_context
, struct key_data
*);
88 struct salt_type
*string_to_key
;
91 struct checksum_type
{
97 void (*checksum
)(krb5_context context
,
99 const void *buf
, size_t len
,
102 krb5_error_code (*verify
)(krb5_context context
,
103 struct key_data
*key
,
104 const void *buf
, size_t len
,
109 struct encryption_type
{
114 size_t confoundersize
;
115 struct key_type
*keytype
;
116 struct checksum_type
*checksum
;
117 struct checksum_type
*keyed_checksum
;
119 krb5_error_code (*encrypt
)(krb5_context context
,
120 struct key_data
*key
,
121 void *data
, size_t len
,
122 krb5_boolean encrypt
,
127 #define ENCRYPTION_USAGE(U) (((U) << 8) | 0xAA)
128 #define INTEGRITY_USAGE(U) (((U) << 8) | 0x55)
129 #define CHECKSUM_USAGE(U) (((U) << 8) | 0x99)
131 static struct checksum_type
*_find_checksum(krb5_cksumtype type
);
132 static struct encryption_type
*_find_enctype(krb5_enctype type
);
133 static struct key_type
*_find_keytype(krb5_keytype type
);
134 static krb5_error_code
_get_derived_key(krb5_context
, krb5_crypto
,
135 unsigned, struct key_data
**);
136 static struct key_data
*_new_derived_key(krb5_crypto crypto
, unsigned usage
);
137 static krb5_error_code
derive_key(krb5_context context
,
138 struct encryption_type
*et
,
139 struct key_data
*key
,
140 const void *constant
,
142 static krb5_error_code
hmac(krb5_context context
,
143 struct checksum_type
*cm
,
147 struct key_data
*keyblock
,
149 static void free_key_data(krb5_context context
, struct key_data
*key
);
150 static krb5_error_code
usage2arcfour (krb5_context
, int *);
152 /************************************************************
154 ************************************************************/
157 krb5_DES_random_key(krb5_context context
,
160 des_cblock
*k
= key
->keyvalue
.data
;
162 krb5_generate_random_block(k
, sizeof(des_cblock
));
163 des_set_odd_parity(k
);
164 } while(des_is_weak_key(k
));
168 krb5_DES_schedule(krb5_context context
,
169 struct key_data
*key
)
171 des_set_key(key
->key
->keyvalue
.data
, key
->schedule
->data
);
175 DES_string_to_key_int(unsigned char *data
, size_t length
, des_cblock
*key
)
177 des_key_schedule schedule
;
182 unsigned char swap
[] = { 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
183 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf };
186 p
= (unsigned char*)key
;
187 for (i
= 0; i
< length
; i
++) {
188 unsigned char tmp
= data
[i
];
192 *--p
^= (swap
[tmp
& 0xf] << 4) | swap
[(tmp
& 0xf0) >> 4];
196 des_set_odd_parity(key
);
197 if(des_is_weak_key(key
))
199 des_set_key(key
, schedule
);
200 des_cbc_cksum((void*)data
, key
, length
, schedule
, key
);
201 memset(schedule
, 0, sizeof(schedule
));
202 des_set_odd_parity(key
);
205 static krb5_error_code
206 krb5_DES_string_to_key(krb5_context context
,
207 krb5_enctype enctype
,
217 len
= password
.length
+ salt
.saltvalue
.length
;
219 if(len
> 0 && s
== NULL
) {
220 krb5_set_error_string(context
, "malloc: out of memory");
223 memcpy(s
, password
.data
, password
.length
);
224 memcpy(s
+ password
.length
, salt
.saltvalue
.data
, salt
.saltvalue
.length
);
225 DES_string_to_key_int(s
, len
, &tmp
);
226 key
->keytype
= enctype
;
227 krb5_data_copy(&key
->keyvalue
, tmp
, sizeof(tmp
));
228 memset(&tmp
, 0, sizeof(tmp
));
234 /* This defines the Andrew string_to_key function. It accepts a password
235 * string as input and converts its via a one-way encryption algorithm to a DES
236 * encryption key. It is compatible with the original Andrew authentication
237 * service password database.
241 * Short passwords, i.e 8 characters or less.
244 krb5_DES_AFS3_CMU_string_to_key (krb5_data pw
,
248 char password
[8+1]; /* crypt is limited to 8 chars anyway */
251 for(i
= 0; i
< 8; i
++) {
252 char c
= ((i
< pw
.length
) ? ((char*)pw
.data
)[i
] : 0) ^
254 tolower(((unsigned char*)cell
.data
)[i
]) : 0);
255 password
[i
] = c
? c
: 'X';
259 memcpy(key
, crypt(password
, "p1") + 2, sizeof(des_cblock
));
261 /* parity is inserted into the LSB so left shift each byte up one
262 bit. This allows ascii characters with a zero MSB to retain as
263 much significance as possible. */
264 for (i
= 0; i
< sizeof(des_cblock
); i
++)
265 ((unsigned char*)key
)[i
] <<= 1;
266 des_set_odd_parity (key
);
270 * Long passwords, i.e 9 characters or more.
273 krb5_DES_AFS3_Transarc_string_to_key (krb5_data pw
,
277 des_key_schedule schedule
;
283 memcpy(password
, pw
.data
, min(pw
.length
, sizeof(password
)));
284 if(pw
.length
< sizeof(password
)) {
285 int len
= min(cell
.length
, sizeof(password
) - pw
.length
);
288 memcpy(password
+ pw
.length
, cell
.data
, len
);
289 for (i
= pw
.length
; i
< pw
.length
+ len
; ++i
)
290 password
[i
] = tolower((unsigned char)password
[i
]);
292 passlen
= min(sizeof(password
), pw
.length
+ cell
.length
);
293 memcpy(&ivec
, "kerberos", 8);
294 memcpy(&temp_key
, "kerberos", 8);
295 des_set_odd_parity (&temp_key
);
296 des_set_key (&temp_key
, schedule
);
297 des_cbc_cksum (password
, &ivec
, passlen
, schedule
, &ivec
);
299 memcpy(&temp_key
, &ivec
, 8);
300 des_set_odd_parity (&temp_key
);
301 des_set_key (&temp_key
, schedule
);
302 des_cbc_cksum (password
, key
, passlen
, schedule
, &ivec
);
303 memset(&schedule
, 0, sizeof(schedule
));
304 memset(&temp_key
, 0, sizeof(temp_key
));
305 memset(&ivec
, 0, sizeof(ivec
));
306 memset(password
, 0, sizeof(password
));
308 des_set_odd_parity (key
);
311 static krb5_error_code
312 DES_AFS3_string_to_key(krb5_context context
,
313 krb5_enctype enctype
,
320 if(password
.length
> 8)
321 krb5_DES_AFS3_Transarc_string_to_key(password
, salt
.saltvalue
, &tmp
);
323 krb5_DES_AFS3_CMU_string_to_key(password
, salt
.saltvalue
, &tmp
);
324 key
->keytype
= enctype
;
325 krb5_data_copy(&key
->keyvalue
, tmp
, sizeof(tmp
));
326 memset(&key
, 0, sizeof(key
));
331 DES3_random_key(krb5_context context
,
334 des_cblock
*k
= key
->keyvalue
.data
;
336 krb5_generate_random_block(k
, 3 * sizeof(des_cblock
));
337 des_set_odd_parity(&k
[0]);
338 des_set_odd_parity(&k
[1]);
339 des_set_odd_parity(&k
[2]);
340 } while(des_is_weak_key(&k
[0]) ||
341 des_is_weak_key(&k
[1]) ||
342 des_is_weak_key(&k
[2]));
346 DES3_schedule(krb5_context context
,
347 struct key_data
*key
)
349 des_cblock
*k
= key
->key
->keyvalue
.data
;
350 des_key_schedule
*s
= key
->schedule
->data
;
351 des_set_key(&k
[0], s
[0]);
352 des_set_key(&k
[1], s
[1]);
353 des_set_key(&k
[2], s
[2]);
357 * A = A xor B. A & B are 8 bytes.
361 xor (des_cblock
*key
, const unsigned char *b
)
363 unsigned char *a
= (unsigned char*)key
;
374 static krb5_error_code
375 DES3_string_to_key(krb5_context context
,
376 krb5_enctype enctype
,
384 unsigned char tmp
[24];
387 len
= password
.length
+ salt
.saltvalue
.length
;
389 if(len
!= 0 && str
== NULL
) {
390 krb5_set_error_string(context
, "malloc: out of memory");
393 memcpy(str
, password
.data
, password
.length
);
394 memcpy(str
+ password
.length
, salt
.saltvalue
.data
, salt
.saltvalue
.length
);
397 des_key_schedule s
[3];
400 _krb5_n_fold(str
, len
, tmp
, 24);
402 for(i
= 0; i
< 3; i
++){
403 memcpy(keys
+ i
, tmp
+ i
* 8, sizeof(keys
[i
]));
404 des_set_odd_parity(keys
+ i
);
405 if(des_is_weak_key(keys
+ i
))
406 xor(keys
+ i
, (const unsigned char*)"\0\0\0\0\0\0\0\xf0");
407 des_set_key(keys
+ i
, s
[i
]);
409 memset(&ivec
, 0, sizeof(ivec
));
410 des_ede3_cbc_encrypt(tmp
,
412 s
[0], s
[1], s
[2], &ivec
, DES_ENCRYPT
);
413 memset(s
, 0, sizeof(s
));
414 memset(&ivec
, 0, sizeof(ivec
));
415 for(i
= 0; i
< 3; i
++){
416 memcpy(keys
+ i
, tmp
+ i
* 8, sizeof(keys
[i
]));
417 des_set_odd_parity(keys
+ i
);
418 if(des_is_weak_key(keys
+ i
))
419 xor(keys
+ i
, (const unsigned char*)"\0\0\0\0\0\0\0\xf0");
421 memset(tmp
, 0, sizeof(tmp
));
423 key
->keytype
= enctype
;
424 krb5_data_copy(&key
->keyvalue
, keys
, sizeof(keys
));
425 memset(keys
, 0, sizeof(keys
));
431 static krb5_error_code
432 DES3_string_to_key_derived(krb5_context context
,
433 krb5_enctype enctype
,
440 size_t len
= password
.length
+ salt
.saltvalue
.length
;
444 if(len
!= 0 && s
== NULL
) {
445 krb5_set_error_string(context
, "malloc: out of memory");
448 memcpy(s
, password
.data
, password
.length
);
449 memcpy(s
+ password
.length
, salt
.saltvalue
.data
, salt
.saltvalue
.length
);
450 ret
= krb5_string_to_key_derived(context
,
465 ARCFOUR_random_key(krb5_context context
, krb5_keyblock
*key
)
467 krb5_generate_random_block (key
->keyvalue
.data
,
468 key
->keyvalue
.length
);
472 ARCFOUR_schedule(krb5_context context
, struct key_data
*kd
)
474 RC4_set_key (kd
->schedule
->data
,
475 kd
->key
->keyvalue
.length
, kd
->key
->keyvalue
.data
);
478 static krb5_error_code
479 ARCFOUR_string_to_key(krb5_context context
,
480 krb5_enctype enctype
,
491 len
= 2 * password
.length
;
493 if (len
!= 0 && s
== NULL
) {
494 krb5_set_error_string(context
, "malloc: out of memory");
497 for (p
= s
, i
= 0; i
< password
.length
; ++i
) {
498 *p
++ = ((char *)password
.data
)[i
];
502 MD4_Update (&m
, s
, len
);
503 key
->keytype
= enctype
;
504 krb5_data_alloc (&key
->keyvalue
, 16);
505 MD4_Final (key
->keyvalue
.data
, &m
);
516 /* iter is really 1 based, so iter == 0 will be 1 iteration */
519 krb5_PKCS5_PBKDF2(krb5_context context
, krb5_cksumtype cktype
,
520 krb5_data password
, krb5_salt salt
, u_int32_t iter
,
521 krb5_keytype type
, krb5_keyblock
*key
)
523 struct checksum_type
*c
= _find_checksum(cktype
);
525 size_t datalen
, leftofkey
;
528 struct key_data ksign
;
531 char *data
, *tmpcksum
;
536 krb5_set_error_string(context
, "checksum %d not supported", cktype
);
537 return KRB5_PROG_KEYTYPE_NOSUPP
;
540 kt
= _find_keytype(type
);
542 krb5_set_error_string(context
, "key type %d not supported", type
);
543 return KRB5_PROG_KEYTYPE_NOSUPP
;
547 ret
= krb5_data_alloc (&key
->keyvalue
, kt
->bits
/ 8);
549 krb5_set_error_string(context
, "malloc: out of memory");
553 ret
= krb5_data_alloc (&result
.checksum
, c
->checksumsize
);
555 krb5_set_error_string(context
, "malloc: out of memory");
556 krb5_data_free (&key
->keyvalue
);
560 tmpcksum
= malloc(c
->checksumsize
);
561 if (tmpcksum
== NULL
) {
562 krb5_set_error_string(context
, "malloc: out of memory");
563 krb5_data_free (&key
->keyvalue
);
564 krb5_data_free (&result
.checksum
);
568 datalen
= salt
.saltvalue
.length
+ 4;
569 data
= malloc(datalen
);
571 krb5_set_error_string(context
, "malloc: out of memory");
573 krb5_data_free (&key
->keyvalue
);
574 krb5_data_free (&result
.checksum
);
578 kb
.keyvalue
= password
;
581 memcpy(data
, salt
.saltvalue
.data
, salt
.saltvalue
.length
);
584 leftofkey
= key
->keyvalue
.length
;
585 p
= key
->keyvalue
.data
;
590 if (leftofkey
> c
->checksumsize
)
591 len
= c
->checksumsize
;
595 _krb5_put_int(data
+ datalen
- 4, keypart
, 4);
597 ret
= hmac(context
, c
, data
, datalen
, 0, &ksign
, &result
);
599 krb5_abortx(context
, "hmac failed");
600 memcpy(p
, result
.checksum
.data
, len
);
601 memcpy(tmpcksum
, result
.checksum
.data
, result
.checksum
.length
);
602 for (i
= 0; i
< iter
; i
++) {
603 ret
= hmac(context
, c
, tmpcksum
, result
.checksum
.length
,
606 krb5_abortx(context
, "hmac failed");
607 memcpy(tmpcksum
, result
.checksum
.data
, result
.checksum
.length
);
608 for (j
= 0; j
< len
; j
++)
619 krb5_data_free (&result
.checksum
);
624 static krb5_error_code
625 AES_string_to_key(krb5_context context
,
626 krb5_enctype enctype
,
634 struct encryption_type
*et
;
637 if (opaque
.length
== 0)
639 else if (opaque
.length
== 4) {
641 _krb5_get_int(opaque
.data
, &v
, 4);
642 iter
= ((u_int32_t
)v
) - 1;
644 return KRB5_PROG_KEYTYPE_NOSUPP
; /* XXX */
647 et
= _find_enctype(enctype
);
649 return KRB5_PROG_KEYTYPE_NOSUPP
;
651 ret
= krb5_PKCS5_PBKDF2(context
, CKSUMTYPE_SHA1
, password
, salt
,
656 ret
= krb5_copy_keyblock(context
, key
, &kd
.key
);
659 ret
= derive_key(context
, et
, &kd
, "kerberos", strlen("kerberos"));
662 krb5_data_free(&key
->keyvalue
);
664 ret
= krb5_copy_keyblock_contents(context
, kd
.key
, key
);
665 free_key_data(context
, &kd
);
672 AES_schedule(krb5_context context
, struct key_data
*kd
)
674 AES_KEY
*key
= kd
->schedule
->data
;
675 int bits
= kd
->key
->keyvalue
.length
* 8;
677 AES_set_encrypt_key(kd
->key
->keyvalue
.data
, bits
, &key
[0]);
678 AES_set_decrypt_key(kd
->key
->keyvalue
.data
, bits
, &key
[1]);
685 extern struct salt_type AES_salt
[];
687 #endif /* ENABLE_AES */
689 extern struct salt_type des_salt
[],
690 des3_salt
[], des3_salt_derived
[], arcfour_salt
[];
692 struct key_type keytype_null
= {
703 struct key_type keytype_des
= {
708 sizeof(des_key_schedule
),
714 struct key_type keytype_des3
= {
718 3 * sizeof(des_cblock
),
719 3 * sizeof(des_key_schedule
),
725 struct key_type keytype_des3_derived
= {
729 3 * sizeof(des_cblock
),
730 3 * sizeof(des_key_schedule
),
737 struct key_type keytype_aes128
= {
748 struct key_type keytype_aes256
= {
758 #endif /* ENABLE_AES */
760 struct key_type keytype_arcfour
= {
771 struct key_type
*keytypes
[] = {
774 &keytype_des3_derived
,
779 #endif /* ENABLE_AES */
783 static int num_keytypes
= sizeof(keytypes
) / sizeof(keytypes
[0]);
785 static struct key_type
*
786 _find_keytype(krb5_keytype type
)
789 for(i
= 0; i
< num_keytypes
; i
++)
790 if(keytypes
[i
]->type
== type
)
796 struct salt_type des_salt
[] = {
800 krb5_DES_string_to_key
805 DES_AFS3_string_to_key
810 struct salt_type des3_salt
[] = {
819 struct salt_type des3_salt_derived
[] = {
823 DES3_string_to_key_derived
829 struct salt_type AES_salt
[] = {
837 #endif /* ENABLE_AES */
839 struct salt_type arcfour_salt
[] = {
843 ARCFOUR_string_to_key
849 krb5_salttype_to_string (krb5_context context
,
854 struct encryption_type
*e
;
855 struct salt_type
*st
;
857 e
= _find_enctype (etype
);
859 krb5_set_error_string(context
, "encryption type %d not supported",
861 return KRB5_PROG_ETYPE_NOSUPP
;
863 for (st
= e
->keytype
->string_to_key
; st
&& st
->type
; st
++) {
864 if (st
->type
== stype
) {
865 *string
= strdup (st
->name
);
866 if (*string
== NULL
) {
867 krb5_set_error_string(context
, "malloc: out of memory");
873 krb5_set_error_string(context
, "salttype %d not supported", stype
);
874 return HEIM_ERR_SALTTYPE_NOSUPP
;
878 krb5_string_to_salttype (krb5_context context
,
881 krb5_salttype
*salttype
)
883 struct encryption_type
*e
;
884 struct salt_type
*st
;
886 e
= _find_enctype (etype
);
888 krb5_set_error_string(context
, "encryption type %d not supported",
890 return KRB5_PROG_ETYPE_NOSUPP
;
892 for (st
= e
->keytype
->string_to_key
; st
&& st
->type
; st
++) {
893 if (strcasecmp (st
->name
, string
) == 0) {
894 *salttype
= st
->type
;
898 krb5_set_error_string(context
, "salttype %s not supported", string
);
899 return HEIM_ERR_SALTTYPE_NOSUPP
;
903 krb5_get_pw_salt(krb5_context context
,
904 krb5_const_principal principal
,
912 salt
->salttype
= KRB5_PW_SALT
;
913 len
= strlen(principal
->realm
);
914 for (i
= 0; i
< principal
->name
.name_string
.len
; ++i
)
915 len
+= strlen(principal
->name
.name_string
.val
[i
]);
916 ret
= krb5_data_alloc (&salt
->saltvalue
, len
);
919 p
= salt
->saltvalue
.data
;
920 memcpy (p
, principal
->realm
, strlen(principal
->realm
));
921 p
+= strlen(principal
->realm
);
922 for (i
= 0; i
< principal
->name
.name_string
.len
; ++i
) {
924 principal
->name
.name_string
.val
[i
],
925 strlen(principal
->name
.name_string
.val
[i
]));
926 p
+= strlen(principal
->name
.name_string
.val
[i
]);
932 krb5_free_salt(krb5_context context
,
935 krb5_data_free(&salt
.saltvalue
);
940 krb5_string_to_key_data (krb5_context context
,
941 krb5_enctype enctype
,
943 krb5_principal principal
,
949 ret
= krb5_get_pw_salt(context
, principal
, &salt
);
952 ret
= krb5_string_to_key_data_salt(context
, enctype
, password
, salt
, key
);
953 krb5_free_salt(context
, salt
);
958 krb5_string_to_key (krb5_context context
,
959 krb5_enctype enctype
,
960 const char *password
,
961 krb5_principal principal
,
965 pw
.data
= (void*)password
;
966 pw
.length
= strlen(password
);
967 return krb5_string_to_key_data(context
, enctype
, pw
, principal
, key
);
971 krb5_string_to_key_data_salt (krb5_context context
,
972 krb5_enctype enctype
,
978 krb5_data_zero(&opaque
);
979 return krb5_string_to_key_data_salt_opaque(context
, enctype
, password
,
984 * Do a string -> key for encryption type `enctype' operation on
985 * `password' (with salt `salt' and the enctype specific data string
986 * `opaque'), returning the resulting key in `key'
990 krb5_string_to_key_data_salt_opaque (krb5_context context
,
991 krb5_enctype enctype
,
997 struct encryption_type
*et
=_find_enctype(enctype
);
998 struct salt_type
*st
;
1000 krb5_set_error_string(context
, "encryption type %d not supported",
1002 return KRB5_PROG_ETYPE_NOSUPP
;
1004 for(st
= et
->keytype
->string_to_key
; st
&& st
->type
; st
++)
1005 if(st
->type
== salt
.salttype
)
1006 return (*st
->string_to_key
)(context
, enctype
, password
,
1008 krb5_set_error_string(context
, "salt type %d not supported",
1010 return HEIM_ERR_SALTTYPE_NOSUPP
;
1014 * Do a string -> key for encryption type `enctype' operation on the
1015 * string `password' (with salt `salt'), returning the resulting key
1020 krb5_string_to_key_salt (krb5_context context
,
1021 krb5_enctype enctype
,
1022 const char *password
,
1027 pw
.data
= (void*)password
;
1028 pw
.length
= strlen(password
);
1029 return krb5_string_to_key_data_salt(context
, enctype
, pw
, salt
, key
);
1033 krb5_keytype_to_string(krb5_context context
,
1034 krb5_keytype keytype
,
1037 struct key_type
*kt
= _find_keytype(keytype
);
1039 krb5_set_error_string(context
, "key type %d not supported", keytype
);
1040 return KRB5_PROG_KEYTYPE_NOSUPP
;
1042 *string
= strdup(kt
->name
);
1043 if(*string
== NULL
) {
1044 krb5_set_error_string(context
, "malloc: out of memory");
1051 krb5_string_to_keytype(krb5_context context
,
1053 krb5_keytype
*keytype
)
1056 for(i
= 0; i
< num_keytypes
; i
++)
1057 if(strcasecmp(keytypes
[i
]->name
, string
) == 0){
1058 *keytype
= keytypes
[i
]->type
;
1061 krb5_set_error_string(context
, "key type %s not supported", string
);
1062 return KRB5_PROG_KEYTYPE_NOSUPP
;
1066 krb5_enctype_keysize(krb5_context context
,
1070 struct encryption_type
*et
= _find_enctype(type
);
1072 krb5_set_error_string(context
, "encryption type %d not supported",
1074 return KRB5_PROG_ETYPE_NOSUPP
;
1076 *keysize
= et
->keytype
->size
;
1081 krb5_generate_random_keyblock(krb5_context context
,
1085 krb5_error_code ret
;
1086 struct encryption_type
*et
= _find_enctype(type
);
1088 krb5_set_error_string(context
, "encryption type %d not supported",
1090 return KRB5_PROG_ETYPE_NOSUPP
;
1092 ret
= krb5_data_alloc(&key
->keyvalue
, et
->keytype
->size
);
1095 key
->keytype
= type
;
1096 if(et
->keytype
->random_key
)
1097 (*et
->keytype
->random_key
)(context
, key
);
1099 krb5_generate_random_block(key
->keyvalue
.data
,
1100 key
->keyvalue
.length
);
1104 static krb5_error_code
1105 _key_schedule(krb5_context context
,
1106 struct key_data
*key
)
1108 krb5_error_code ret
;
1109 struct encryption_type
*et
= _find_enctype(key
->key
->keytype
);
1110 struct key_type
*kt
= et
->keytype
;
1112 if(kt
->schedule
== NULL
)
1114 if (key
->schedule
!= NULL
)
1116 ALLOC(key
->schedule
, 1);
1117 if(key
->schedule
== NULL
) {
1118 krb5_set_error_string(context
, "malloc: out of memory");
1121 ret
= krb5_data_alloc(key
->schedule
, kt
->schedule_size
);
1123 free(key
->schedule
);
1124 key
->schedule
= NULL
;
1127 (*kt
->schedule
)(context
, key
);
1131 /************************************************************
1133 ************************************************************/
1136 NONE_checksum(krb5_context context
,
1137 struct key_data
*key
,
1146 CRC32_checksum(krb5_context context
,
1147 struct key_data
*key
,
1154 unsigned char *r
= C
->checksum
.data
;
1155 _krb5_crc_init_table ();
1156 crc
= _krb5_crc_update (data
, len
, 0);
1158 r
[1] = (crc
>> 8) & 0xff;
1159 r
[2] = (crc
>> 16) & 0xff;
1160 r
[3] = (crc
>> 24) & 0xff;
1164 RSA_MD4_checksum(krb5_context context
,
1165 struct key_data
*key
,
1174 MD4_Update (&m
, data
, len
);
1175 MD4_Final (C
->checksum
.data
, &m
);
1179 RSA_MD4_DES_checksum(krb5_context context
,
1180 struct key_data
*key
,
1188 unsigned char *p
= cksum
->checksum
.data
;
1190 krb5_generate_random_block(p
, 8);
1192 MD4_Update (&md4
, p
, 8);
1193 MD4_Update (&md4
, data
, len
);
1194 MD4_Final (p
+ 8, &md4
);
1195 memset (&ivec
, 0, sizeof(ivec
));
1199 key
->schedule
->data
,
1204 static krb5_error_code
1205 RSA_MD4_DES_verify(krb5_context context
,
1206 struct key_data
*key
,
1213 unsigned char tmp
[24];
1214 unsigned char res
[16];
1216 krb5_error_code ret
= 0;
1218 memset(&ivec
, 0, sizeof(ivec
));
1219 des_cbc_encrypt(C
->checksum
.data
,
1222 key
->schedule
->data
,
1226 MD4_Update (&md4
, tmp
, 8); /* confounder */
1227 MD4_Update (&md4
, data
, len
);
1228 MD4_Final (res
, &md4
);
1229 if(memcmp(res
, tmp
+ 8, sizeof(res
)) != 0) {
1230 krb5_clear_error_string (context
);
1231 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
1233 memset(tmp
, 0, sizeof(tmp
));
1234 memset(res
, 0, sizeof(res
));
1239 RSA_MD5_checksum(krb5_context context
,
1240 struct key_data
*key
,
1249 MD5_Update(&m
, data
, len
);
1250 MD5_Final (C
->checksum
.data
, &m
);
1254 RSA_MD5_DES_checksum(krb5_context context
,
1255 struct key_data
*key
,
1263 unsigned char *p
= C
->checksum
.data
;
1265 krb5_generate_random_block(p
, 8);
1267 MD5_Update (&md5
, p
, 8);
1268 MD5_Update (&md5
, data
, len
);
1269 MD5_Final (p
+ 8, &md5
);
1270 memset (&ivec
, 0, sizeof(ivec
));
1274 key
->schedule
->data
,
1279 static krb5_error_code
1280 RSA_MD5_DES_verify(krb5_context context
,
1281 struct key_data
*key
,
1288 unsigned char tmp
[24];
1289 unsigned char res
[16];
1291 des_key_schedule
*sched
= key
->schedule
->data
;
1292 krb5_error_code ret
= 0;
1294 memset(&ivec
, 0, sizeof(ivec
));
1295 des_cbc_encrypt(C
->checksum
.data
,
1302 MD5_Update (&md5
, tmp
, 8); /* confounder */
1303 MD5_Update (&md5
, data
, len
);
1304 MD5_Final (res
, &md5
);
1305 if(memcmp(res
, tmp
+ 8, sizeof(res
)) != 0) {
1306 krb5_clear_error_string (context
);
1307 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
1309 memset(tmp
, 0, sizeof(tmp
));
1310 memset(res
, 0, sizeof(res
));
1315 RSA_MD5_DES3_checksum(krb5_context context
,
1316 struct key_data
*key
,
1324 unsigned char *p
= C
->checksum
.data
;
1325 des_key_schedule
*sched
= key
->schedule
->data
;
1327 krb5_generate_random_block(p
, 8);
1329 MD5_Update (&md5
, p
, 8);
1330 MD5_Update (&md5
, data
, len
);
1331 MD5_Final (p
+ 8, &md5
);
1332 memset (&ivec
, 0, sizeof(ivec
));
1333 des_ede3_cbc_encrypt(p
,
1336 sched
[0], sched
[1], sched
[2],
1341 static krb5_error_code
1342 RSA_MD5_DES3_verify(krb5_context context
,
1343 struct key_data
*key
,
1350 unsigned char tmp
[24];
1351 unsigned char res
[16];
1353 des_key_schedule
*sched
= key
->schedule
->data
;
1354 krb5_error_code ret
= 0;
1356 memset(&ivec
, 0, sizeof(ivec
));
1357 des_ede3_cbc_encrypt(C
->checksum
.data
,
1360 sched
[0], sched
[1], sched
[2],
1364 MD5_Update (&md5
, tmp
, 8); /* confounder */
1365 MD5_Update (&md5
, data
, len
);
1366 MD5_Final (res
, &md5
);
1367 if(memcmp(res
, tmp
+ 8, sizeof(res
)) != 0) {
1368 krb5_clear_error_string (context
);
1369 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
1371 memset(tmp
, 0, sizeof(tmp
));
1372 memset(res
, 0, sizeof(res
));
1377 SHA1_checksum(krb5_context context
,
1378 struct key_data
*key
,
1387 SHA1_Update(&m
, data
, len
);
1388 SHA1_Final(C
->checksum
.data
, &m
);
1391 /* HMAC according to RFC2104 */
1392 static krb5_error_code
1393 hmac(krb5_context context
,
1394 struct checksum_type
*cm
,
1398 struct key_data
*keyblock
,
1401 unsigned char *ipad
, *opad
;
1406 ipad
= malloc(cm
->blocksize
+ len
);
1409 opad
= malloc(cm
->blocksize
+ cm
->checksumsize
);
1414 memset(ipad
, 0x36, cm
->blocksize
);
1415 memset(opad
, 0x5c, cm
->blocksize
);
1417 if(keyblock
->key
->keyvalue
.length
> cm
->blocksize
){
1418 (*cm
->checksum
)(context
,
1420 keyblock
->key
->keyvalue
.data
,
1421 keyblock
->key
->keyvalue
.length
,
1424 key
= result
->checksum
.data
;
1425 key_len
= result
->checksum
.length
;
1427 key
= keyblock
->key
->keyvalue
.data
;
1428 key_len
= keyblock
->key
->keyvalue
.length
;
1430 for(i
= 0; i
< key_len
; i
++){
1434 memcpy(ipad
+ cm
->blocksize
, data
, len
);
1435 (*cm
->checksum
)(context
, keyblock
, ipad
, cm
->blocksize
+ len
,
1437 memcpy(opad
+ cm
->blocksize
, result
->checksum
.data
,
1438 result
->checksum
.length
);
1439 (*cm
->checksum
)(context
, keyblock
, opad
,
1440 cm
->blocksize
+ cm
->checksumsize
, usage
, result
);
1441 memset(ipad
, 0, cm
->blocksize
+ len
);
1443 memset(opad
, 0, cm
->blocksize
+ cm
->checksumsize
);
1450 krb5_hmac(krb5_context context
,
1451 krb5_cksumtype cktype
,
1458 struct checksum_type
*c
= _find_checksum(cktype
);
1460 krb5_error_code ret
;
1463 krb5_set_error_string (context
, "checksum type %d not supported",
1465 return KRB5_PROG_SUMTYPE_NOSUPP
;
1471 ret
= hmac(context
, c
, data
, len
, usage
, &kd
, result
);
1474 krb5_free_data(context
, kd
.schedule
);
1480 SP_HMAC_SHA1_checksum(krb5_context context
,
1481 struct key_data
*key
,
1487 struct checksum_type
*c
= _find_checksum(CKSUMTYPE_SHA1
);
1490 krb5_error_code ret
;
1492 res
.checksum
.data
= sha1_data
;
1493 res
.checksum
.length
= sizeof(sha1_data
);
1495 ret
= hmac(context
, c
, data
, len
, usage
, key
, &res
);
1497 krb5_abortx(context
, "hmac failed");
1498 memcpy(result
->checksum
.data
, res
.checksum
.data
, result
->checksum
.length
);
1502 * checksum according to section 5. of draft-brezak-win2k-krb-rc4-hmac-03.txt
1506 HMAC_MD5_checksum(krb5_context context
,
1507 struct key_data
*key
,
1514 struct checksum_type
*c
= _find_checksum (CKSUMTYPE_RSA_MD5
);
1515 const char signature
[] = "signaturekey";
1517 struct key_data ksign
;
1520 unsigned char tmp
[16];
1521 unsigned char ksign_c_data
[16];
1522 krb5_error_code ret
;
1524 ksign_c
.checksum
.length
= sizeof(ksign_c_data
);
1525 ksign_c
.checksum
.data
= ksign_c_data
;
1526 ret
= hmac(context
, c
, signature
, sizeof(signature
), 0, key
, &ksign_c
);
1528 krb5_abortx(context
, "hmac failed");
1530 kb
.keyvalue
= ksign_c
.checksum
;
1532 t
[0] = (usage
>> 0) & 0xFF;
1533 t
[1] = (usage
>> 8) & 0xFF;
1534 t
[2] = (usage
>> 16) & 0xFF;
1535 t
[3] = (usage
>> 24) & 0xFF;
1536 MD5_Update (&md5
, t
, 4);
1537 MD5_Update (&md5
, data
, len
);
1538 MD5_Final (tmp
, &md5
);
1539 ret
= hmac(context
, c
, tmp
, sizeof(tmp
), 0, &ksign
, result
);
1541 krb5_abortx(context
, "hmac failed");
1545 * same as previous but being used while encrypting.
1549 HMAC_MD5_checksum_enc(krb5_context context
,
1550 struct key_data
*key
,
1556 struct checksum_type
*c
= _find_checksum (CKSUMTYPE_RSA_MD5
);
1558 struct key_data ksign
;
1561 unsigned char ksign_c_data
[16];
1562 krb5_error_code ret
;
1564 t
[0] = (usage
>> 0) & 0xFF;
1565 t
[1] = (usage
>> 8) & 0xFF;
1566 t
[2] = (usage
>> 16) & 0xFF;
1567 t
[3] = (usage
>> 24) & 0xFF;
1569 ksign_c
.checksum
.length
= sizeof(ksign_c_data
);
1570 ksign_c
.checksum
.data
= ksign_c_data
;
1571 ret
= hmac(context
, c
, t
, sizeof(t
), 0, key
, &ksign_c
);
1573 krb5_abortx(context
, "hmac failed");
1575 kb
.keyvalue
= ksign_c
.checksum
;
1576 ret
= hmac(context
, c
, data
, len
, 0, &ksign
, result
);
1578 krb5_abortx(context
, "hmac failed");
1581 struct checksum_type checksum_none
= {
1590 struct checksum_type checksum_crc32
= {
1599 struct checksum_type checksum_rsa_md4
= {
1608 struct checksum_type checksum_rsa_md4_des
= {
1609 CKSUMTYPE_RSA_MD4_DES
,
1613 F_KEYED
| F_CPROOF
| F_VARIANT
,
1614 RSA_MD4_DES_checksum
,
1618 struct checksum_type checksum_des_mac
= {
1626 struct checksum_type checksum_des_mac_k
= {
1627 CKSUMTYPE_DES_MAC_K
,
1634 struct checksum_type checksum_rsa_md4_des_k
= {
1635 CKSUMTYPE_RSA_MD4_DES_K
,
1640 RSA_MD4_DES_K_checksum
,
1641 RSA_MD4_DES_K_verify
1644 struct checksum_type checksum_rsa_md5
= {
1653 struct checksum_type checksum_rsa_md5_des
= {
1654 CKSUMTYPE_RSA_MD5_DES
,
1658 F_KEYED
| F_CPROOF
| F_VARIANT
,
1659 RSA_MD5_DES_checksum
,
1662 struct checksum_type checksum_rsa_md5_des3
= {
1663 CKSUMTYPE_RSA_MD5_DES3
,
1667 F_KEYED
| F_CPROOF
| F_VARIANT
,
1668 RSA_MD5_DES3_checksum
,
1671 struct checksum_type checksum_sha1
= {
1680 struct checksum_type checksum_hmac_sha1_des3
= {
1681 CKSUMTYPE_HMAC_SHA1_DES3
,
1685 F_KEYED
| F_CPROOF
| F_DERIVED
,
1686 SP_HMAC_SHA1_checksum
,
1691 struct checksum_type checksum_hmac_sha1_aes128
= {
1692 CKSUMTYPE_HMAC_SHA1_96_AES_128
,
1693 "hmac-sha1-96-aes128",
1696 F_KEYED
| F_CPROOF
| F_DERIVED
,
1697 SP_HMAC_SHA1_checksum
,
1701 struct checksum_type checksum_hmac_sha1_aes256
= {
1702 CKSUMTYPE_HMAC_SHA1_96_AES_256
,
1703 "hmac-sha1-96-aes256",
1706 F_KEYED
| F_CPROOF
| F_DERIVED
,
1707 SP_HMAC_SHA1_checksum
,
1710 #endif /* ENABLE_AES */
1712 struct checksum_type checksum_hmac_md5
= {
1722 struct checksum_type checksum_hmac_md5_enc
= {
1723 CKSUMTYPE_HMAC_MD5_ENC
,
1727 F_KEYED
| F_CPROOF
| F_PSEUDO
,
1728 HMAC_MD5_checksum_enc
,
1732 struct checksum_type
*checksum_types
[] = {
1736 &checksum_rsa_md4_des
,
1739 &checksum_des_mac_k
,
1740 &checksum_rsa_md4_des_k
,
1743 &checksum_rsa_md5_des
,
1744 &checksum_rsa_md5_des3
,
1746 &checksum_hmac_sha1_des3
,
1748 &checksum_hmac_sha1_aes128
,
1749 &checksum_hmac_sha1_aes256
,
1752 &checksum_hmac_md5_enc
1755 static int num_checksums
= sizeof(checksum_types
) / sizeof(checksum_types
[0]);
1757 static struct checksum_type
*
1758 _find_checksum(krb5_cksumtype type
)
1761 for(i
= 0; i
< num_checksums
; i
++)
1762 if(checksum_types
[i
]->type
== type
)
1763 return checksum_types
[i
];
1767 static krb5_error_code
1768 get_checksum_key(krb5_context context
,
1770 unsigned usage
, /* not krb5_key_usage */
1771 struct checksum_type
*ct
,
1772 struct key_data
**key
)
1774 krb5_error_code ret
= 0;
1776 if(ct
->flags
& F_DERIVED
)
1777 ret
= _get_derived_key(context
, crypto
, usage
, key
);
1778 else if(ct
->flags
& F_VARIANT
) {
1781 *key
= _new_derived_key(crypto
, 0xff/* KRB5_KU_RFC1510_VARIANT */);
1783 krb5_set_error_string(context
, "malloc: out of memory");
1786 ret
= krb5_copy_keyblock(context
, crypto
->key
.key
, &(*key
)->key
);
1789 for(i
= 0; i
< (*key
)->key
->keyvalue
.length
; i
++)
1790 ((unsigned char*)(*key
)->key
->keyvalue
.data
)[i
] ^= 0xF0;
1792 *key
= &crypto
->key
;
1795 ret
= _key_schedule(context
, *key
);
1799 static krb5_error_code
1800 create_checksum (krb5_context context
,
1801 struct checksum_type
*ct
,
1808 krb5_error_code ret
;
1809 struct key_data
*dkey
;
1812 keyed_checksum
= (ct
->flags
& F_KEYED
) != 0;
1813 if(keyed_checksum
&& crypto
== NULL
) {
1814 krb5_clear_error_string (context
);
1815 return KRB5_PROG_SUMTYPE_NOSUPP
; /* XXX */
1817 if(keyed_checksum
) {
1818 ret
= get_checksum_key(context
, crypto
, usage
, ct
, &dkey
);
1823 result
->cksumtype
= ct
->type
;
1824 krb5_data_alloc(&result
->checksum
, ct
->checksumsize
);
1825 (*ct
->checksum
)(context
, dkey
, data
, len
, usage
, result
);
1830 arcfour_checksum_p(struct checksum_type
*ct
, krb5_crypto crypto
)
1832 return (ct
->type
== CKSUMTYPE_HMAC_MD5
) &&
1833 (crypto
->key
.key
->keytype
== KEYTYPE_ARCFOUR
);
1837 krb5_create_checksum(krb5_context context
,
1839 krb5_key_usage usage
,
1845 struct checksum_type
*ct
= NULL
;
1848 /* type 0 -> pick from crypto */
1850 ct
= _find_checksum(type
);
1851 } else if (crypto
) {
1852 ct
= crypto
->et
->keyed_checksum
;
1854 ct
= crypto
->et
->checksum
;
1858 krb5_set_error_string (context
, "checksum type %d not supported",
1860 return KRB5_PROG_SUMTYPE_NOSUPP
;
1863 if (arcfour_checksum_p(ct
, crypto
)) {
1865 usage2arcfour(context
, &keyusage
);
1867 keyusage
= CHECKSUM_USAGE(usage
);
1869 return create_checksum(context
, ct
, crypto
, keyusage
,
1873 static krb5_error_code
1874 verify_checksum(krb5_context context
,
1876 unsigned usage
, /* not krb5_key_usage */
1881 krb5_error_code ret
;
1882 struct key_data
*dkey
;
1885 struct checksum_type
*ct
;
1887 ct
= _find_checksum(cksum
->cksumtype
);
1889 krb5_set_error_string (context
, "checksum type %d not supported",
1891 return KRB5_PROG_SUMTYPE_NOSUPP
;
1893 if(ct
->checksumsize
!= cksum
->checksum
.length
) {
1894 krb5_clear_error_string (context
);
1895 return KRB5KRB_AP_ERR_BAD_INTEGRITY
; /* XXX */
1897 keyed_checksum
= (ct
->flags
& F_KEYED
) != 0;
1898 if(keyed_checksum
&& crypto
== NULL
) {
1899 krb5_clear_error_string (context
);
1900 return KRB5_PROG_SUMTYPE_NOSUPP
; /* XXX */
1903 ret
= get_checksum_key(context
, crypto
, usage
, ct
, &dkey
);
1907 return (*ct
->verify
)(context
, dkey
, data
, len
, usage
, cksum
);
1909 ret
= krb5_data_alloc (&c
.checksum
, ct
->checksumsize
);
1913 (*ct
->checksum
)(context
, dkey
, data
, len
, usage
, &c
);
1915 if(c
.checksum
.length
!= cksum
->checksum
.length
||
1916 memcmp(c
.checksum
.data
, cksum
->checksum
.data
, c
.checksum
.length
)) {
1917 krb5_clear_error_string (context
);
1918 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
1922 krb5_data_free (&c
.checksum
);
1927 krb5_verify_checksum(krb5_context context
,
1929 krb5_key_usage usage
,
1934 struct checksum_type
*ct
;
1937 ct
= _find_checksum(cksum
->cksumtype
);
1939 krb5_set_error_string (context
, "checksum type %d not supported",
1941 return KRB5_PROG_SUMTYPE_NOSUPP
;
1944 if (arcfour_checksum_p(ct
, crypto
)) {
1946 usage2arcfour(context
, &keyusage
);
1948 keyusage
= CHECKSUM_USAGE(usage
);
1950 return verify_checksum(context
, crypto
, keyusage
,
1955 krb5_checksumsize(krb5_context context
,
1956 krb5_cksumtype type
,
1959 struct checksum_type
*ct
= _find_checksum(type
);
1961 krb5_set_error_string (context
, "checksum type %d not supported",
1963 return KRB5_PROG_SUMTYPE_NOSUPP
;
1965 *size
= ct
->checksumsize
;
1970 krb5_checksum_is_keyed(krb5_context context
,
1971 krb5_cksumtype type
)
1973 struct checksum_type
*ct
= _find_checksum(type
);
1975 krb5_set_error_string (context
, "checksum type %d not supported",
1977 return KRB5_PROG_SUMTYPE_NOSUPP
;
1979 return ct
->flags
& F_KEYED
;
1983 krb5_checksum_is_collision_proof(krb5_context context
,
1984 krb5_cksumtype type
)
1986 struct checksum_type
*ct
= _find_checksum(type
);
1988 krb5_set_error_string (context
, "checksum type %d not supported",
1990 return KRB5_PROG_SUMTYPE_NOSUPP
;
1992 return ct
->flags
& F_CPROOF
;
1995 /************************************************************
1997 ************************************************************/
1999 static krb5_error_code
2000 NULL_encrypt(krb5_context context
,
2001 struct key_data
*key
,
2004 krb5_boolean encrypt
,
2011 static krb5_error_code
2012 DES_CBC_encrypt_null_ivec(krb5_context context
,
2013 struct key_data
*key
,
2016 krb5_boolean encrypt
,
2021 des_key_schedule
*s
= key
->schedule
->data
;
2022 memset(&ivec
, 0, sizeof(ivec
));
2023 des_cbc_encrypt(data
, data
, len
, *s
, &ivec
, encrypt
);
2027 static krb5_error_code
2028 DES_CBC_encrypt_key_ivec(krb5_context context
,
2029 struct key_data
*key
,
2032 krb5_boolean encrypt
,
2037 des_key_schedule
*s
= key
->schedule
->data
;
2038 memcpy(&ivec
, key
->key
->keyvalue
.data
, sizeof(ivec
));
2039 des_cbc_encrypt(data
, data
, len
, *s
, &ivec
, encrypt
);
2043 static krb5_error_code
2044 DES3_CBC_encrypt(krb5_context context
,
2045 struct key_data
*key
,
2048 krb5_boolean encrypt
,
2052 des_cblock local_ivec
;
2053 des_key_schedule
*s
= key
->schedule
->data
;
2056 memset(local_ivec
, 0, sizeof(local_ivec
));
2058 des_ede3_cbc_encrypt(data
, data
, len
, s
[0], s
[1], s
[2], ivec
, encrypt
);
2062 static krb5_error_code
2063 DES_CFB64_encrypt_null_ivec(krb5_context context
,
2064 struct key_data
*key
,
2067 krb5_boolean encrypt
,
2073 des_key_schedule
*s
= key
->schedule
->data
;
2074 memset(&ivec
, 0, sizeof(ivec
));
2076 des_cfb64_encrypt(data
, data
, len
, *s
, &ivec
, &num
, encrypt
);
2080 static krb5_error_code
2081 DES_PCBC_encrypt_key_ivec(krb5_context context
,
2082 struct key_data
*key
,
2085 krb5_boolean encrypt
,
2090 des_key_schedule
*s
= key
->schedule
->data
;
2091 memcpy(&ivec
, key
->key
->keyvalue
.data
, sizeof(ivec
));
2093 des_pcbc_encrypt(data
, data
, len
, *s
, &ivec
, encrypt
);
2100 * AES draft-raeburn-krb-rijndael-krb-02
2104 _krb5_aes_cts_encrypt(const unsigned char *in
, unsigned char *out
,
2105 size_t len
, const void *aes_key
,
2106 unsigned char *ivec
, const int enc
)
2108 unsigned char tmp
[AES_BLOCK_SIZE
];
2109 const AES_KEY
*key
= aes_key
; /* XXX remove this when we always have AES */
2113 * In the framework of kerberos, the length can never be shorter
2114 * then at least one blocksize.
2117 if (enc
== AES_ENCRYPT
) {
2119 while(len
> AES_BLOCK_SIZE
) {
2120 for (i
= 0; i
< AES_BLOCK_SIZE
; i
++)
2121 tmp
[i
] = in
[i
] ^ ivec
[i
];
2122 AES_encrypt(tmp
, out
, key
);
2123 memcpy(ivec
, out
, AES_BLOCK_SIZE
);
2124 len
-= AES_BLOCK_SIZE
;
2125 in
+= AES_BLOCK_SIZE
;
2126 out
+= AES_BLOCK_SIZE
;
2129 for (i
= 0; i
< len
; i
++)
2130 tmp
[i
] = in
[i
] ^ ivec
[i
];
2131 for (; i
< AES_BLOCK_SIZE
; i
++)
2132 tmp
[i
] = 0 ^ ivec
[i
];
2134 AES_encrypt(tmp
, out
- AES_BLOCK_SIZE
, key
);
2136 memcpy(out
, ivec
, len
);
2139 char tmp2
[AES_BLOCK_SIZE
];
2140 char tmp3
[AES_BLOCK_SIZE
];
2142 while(len
> AES_BLOCK_SIZE
* 2) {
2143 memcpy(tmp
, in
, AES_BLOCK_SIZE
);
2144 AES_decrypt(in
, out
, key
);
2145 for (i
= 0; i
< AES_BLOCK_SIZE
; i
++)
2147 memcpy(ivec
, tmp
, AES_BLOCK_SIZE
);
2148 len
-= AES_BLOCK_SIZE
;
2149 in
+= AES_BLOCK_SIZE
;
2150 out
+= AES_BLOCK_SIZE
;
2153 len
-= AES_BLOCK_SIZE
;
2155 AES_decrypt(in
, tmp2
, key
);
2157 memcpy(tmp3
, in
+ AES_BLOCK_SIZE
, len
);
2158 memcpy(tmp3
+ len
, tmp2
+ len
, AES_BLOCK_SIZE
- len
); /* xor 0 */
2160 for (i
= 0; i
< len
; i
++)
2161 out
[i
+ AES_BLOCK_SIZE
] = tmp2
[i
] ^ tmp3
[i
];
2163 AES_decrypt(tmp3
, out
, key
);
2164 for (i
= 0; i
< AES_BLOCK_SIZE
; i
++)
2169 static krb5_error_code
2170 AES_CTS_encrypt(krb5_context context
,
2171 struct key_data
*key
,
2174 krb5_boolean encrypt
,
2178 AES_KEY
*k
= key
->schedule
->data
;
2179 char local_ivec
[AES_BLOCK_SIZE
];
2186 if (len
< AES_BLOCK_SIZE
)
2187 krb5_abortx(context
, "invalid use of AES_CTS_encrypt");
2188 if (len
== AES_BLOCK_SIZE
) {
2190 AES_encrypt(data
, data
, k
);
2192 AES_decrypt(data
, data
, k
);
2195 memset(local_ivec
, 0, sizeof(local_ivec
));
2198 _krb5_aes_cts_encrypt(data
, data
, len
, k
, ivec
, encrypt
);
2203 #endif /* ENABLE_AES */
2206 * section 6 of draft-brezak-win2k-krb-rc4-hmac-03
2208 * warning: not for small children
2211 static krb5_error_code
2212 ARCFOUR_subencrypt(krb5_context context
,
2213 struct key_data
*key
,
2219 struct checksum_type
*c
= _find_checksum (CKSUMTYPE_RSA_MD5
);
2220 Checksum k1_c
, k2_c
, k3_c
, cksum
;
2225 unsigned char *cdata
= data
;
2226 unsigned char k1_c_data
[16], k2_c_data
[16], k3_c_data
[16];
2227 krb5_error_code ret
;
2229 t
[0] = (usage
>> 0) & 0xFF;
2230 t
[1] = (usage
>> 8) & 0xFF;
2231 t
[2] = (usage
>> 16) & 0xFF;
2232 t
[3] = (usage
>> 24) & 0xFF;
2234 k1_c
.checksum
.length
= sizeof(k1_c_data
);
2235 k1_c
.checksum
.data
= k1_c_data
;
2237 ret
= hmac(NULL
, c
, t
, sizeof(t
), 0, key
, &k1_c
);
2239 krb5_abortx(context
, "hmac failed");
2241 memcpy (k2_c_data
, k1_c_data
, sizeof(k1_c_data
));
2243 k2_c
.checksum
.length
= sizeof(k2_c_data
);
2244 k2_c
.checksum
.data
= k2_c_data
;
2247 kb
.keyvalue
= k2_c
.checksum
;
2249 cksum
.checksum
.length
= 16;
2250 cksum
.checksum
.data
= data
;
2252 ret
= hmac(NULL
, c
, cdata
+ 16, len
- 16, 0, &ke
, &cksum
);
2254 krb5_abortx(context
, "hmac failed");
2257 kb
.keyvalue
= k1_c
.checksum
;
2259 k3_c
.checksum
.length
= sizeof(k3_c_data
);
2260 k3_c
.checksum
.data
= k3_c_data
;
2262 ret
= hmac(NULL
, c
, data
, 16, 0, &ke
, &k3_c
);
2264 krb5_abortx(context
, "hmac failed");
2266 RC4_set_key (&rc4_key
, k3_c
.checksum
.length
, k3_c
.checksum
.data
);
2267 RC4 (&rc4_key
, len
- 16, cdata
+ 16, cdata
+ 16);
2268 memset (k1_c_data
, 0, sizeof(k1_c_data
));
2269 memset (k2_c_data
, 0, sizeof(k2_c_data
));
2270 memset (k3_c_data
, 0, sizeof(k3_c_data
));
2274 static krb5_error_code
2275 ARCFOUR_subdecrypt(krb5_context context
,
2276 struct key_data
*key
,
2282 struct checksum_type
*c
= _find_checksum (CKSUMTYPE_RSA_MD5
);
2283 Checksum k1_c
, k2_c
, k3_c
, cksum
;
2288 unsigned char *cdata
= data
;
2289 unsigned char k1_c_data
[16], k2_c_data
[16], k3_c_data
[16];
2290 unsigned char cksum_data
[16];
2291 krb5_error_code ret
;
2293 t
[0] = (usage
>> 0) & 0xFF;
2294 t
[1] = (usage
>> 8) & 0xFF;
2295 t
[2] = (usage
>> 16) & 0xFF;
2296 t
[3] = (usage
>> 24) & 0xFF;
2298 k1_c
.checksum
.length
= sizeof(k1_c_data
);
2299 k1_c
.checksum
.data
= k1_c_data
;
2301 ret
= hmac(NULL
, c
, t
, sizeof(t
), 0, key
, &k1_c
);
2303 krb5_abortx(context
, "hmac failed");
2305 memcpy (k2_c_data
, k1_c_data
, sizeof(k1_c_data
));
2307 k2_c
.checksum
.length
= sizeof(k2_c_data
);
2308 k2_c
.checksum
.data
= k2_c_data
;
2311 kb
.keyvalue
= k1_c
.checksum
;
2313 k3_c
.checksum
.length
= sizeof(k3_c_data
);
2314 k3_c
.checksum
.data
= k3_c_data
;
2316 ret
= hmac(NULL
, c
, cdata
, 16, 0, &ke
, &k3_c
);
2318 krb5_abortx(context
, "hmac failed");
2320 RC4_set_key (&rc4_key
, k3_c
.checksum
.length
, k3_c
.checksum
.data
);
2321 RC4 (&rc4_key
, len
- 16, cdata
+ 16, cdata
+ 16);
2324 kb
.keyvalue
= k2_c
.checksum
;
2326 cksum
.checksum
.length
= 16;
2327 cksum
.checksum
.data
= cksum_data
;
2329 ret
= hmac(NULL
, c
, cdata
+ 16, len
- 16, 0, &ke
, &cksum
);
2331 krb5_abortx(context
, "hmac failed");
2333 memset (k1_c_data
, 0, sizeof(k1_c_data
));
2334 memset (k2_c_data
, 0, sizeof(k2_c_data
));
2335 memset (k3_c_data
, 0, sizeof(k3_c_data
));
2337 if (memcmp (cksum
.checksum
.data
, data
, 16) != 0) {
2338 krb5_clear_error_string (context
);
2339 return KRB5KRB_AP_ERR_BAD_INTEGRITY
;
2346 * convert the usage numbers used in
2347 * draft-ietf-cat-kerb-key-derivation-00.txt to the ones in
2348 * draft-brezak-win2k-krb-rc4-hmac-04.txt
2351 static krb5_error_code
2352 usage2arcfour (krb5_context context
, int *usage
)
2355 case KRB5_KU_AS_REP_ENC_PART
: /* 3 */
2356 case KRB5_KU_TGS_REP_ENC_PART_SUB_KEY
: /* 9 */
2359 case KRB5_KU_USAGE_SEAL
: /* 22 */
2362 case KRB5_KU_USAGE_SIGN
: /* 23 */
2365 case KRB5_KU_USAGE_SEQ
: /* 24 */
2373 static krb5_error_code
2374 ARCFOUR_encrypt(krb5_context context
,
2375 struct key_data
*key
,
2378 krb5_boolean encrypt
,
2382 krb5_error_code ret
;
2383 if((ret
= usage2arcfour (context
, &usage
)) != 0)
2387 return ARCFOUR_subencrypt (context
, key
, data
, len
, usage
, ivec
);
2389 return ARCFOUR_subdecrypt (context
, key
, data
, len
, usage
, ivec
);
2394 * these should currently be in reverse preference order.
2395 * (only relevant for !F_PSEUDO) */
2397 static struct encryption_type enctype_null
= {
2409 static struct encryption_type enctype_des_cbc_crc
= {
2419 DES_CBC_encrypt_key_ivec
,
2421 static struct encryption_type enctype_des_cbc_md4
= {
2429 &checksum_rsa_md4_des
,
2431 DES_CBC_encrypt_null_ivec
,
2433 static struct encryption_type enctype_des_cbc_md5
= {
2441 &checksum_rsa_md5_des
,
2443 DES_CBC_encrypt_null_ivec
,
2445 static struct encryption_type enctype_arcfour_hmac_md5
= {
2446 ETYPE_ARCFOUR_HMAC_MD5
,
2453 /* &checksum_hmac_md5_enc */ NULL
,
2457 static struct encryption_type enctype_des3_cbc_md5
= {
2465 &checksum_rsa_md5_des3
,
2469 static struct encryption_type enctype_des3_cbc_sha1
= {
2470 ETYPE_DES3_CBC_SHA1
,
2475 &keytype_des3_derived
,
2477 &checksum_hmac_sha1_des3
,
2481 static struct encryption_type enctype_old_des3_cbc_sha1
= {
2482 ETYPE_OLD_DES3_CBC_SHA1
,
2483 "old-des3-cbc-sha1",
2489 &checksum_hmac_sha1_des3
,
2494 static struct encryption_type enctype_aes128_cts_hmac_sha1
= {
2495 ETYPE_AES128_CTS_HMAC_SHA1_96
,
2496 "aes128-cts-hmac-sha1-96",
2502 &checksum_hmac_sha1_aes128
,
2506 static struct encryption_type enctype_aes256_cts_hmac_sha1
= {
2507 ETYPE_AES256_CTS_HMAC_SHA1_96
,
2508 "aes256-cts-hmac-sha1-96",
2514 &checksum_hmac_sha1_aes256
,
2518 #endif /* ENABLE_AES */
2519 static struct encryption_type enctype_des_cbc_none
= {
2529 DES_CBC_encrypt_null_ivec
,
2531 static struct encryption_type enctype_des_cfb64_none
= {
2532 ETYPE_DES_CFB64_NONE
,
2541 DES_CFB64_encrypt_null_ivec
,
2543 static struct encryption_type enctype_des_pcbc_none
= {
2544 ETYPE_DES_PCBC_NONE
,
2553 DES_PCBC_encrypt_key_ivec
,
2555 static struct encryption_type enctype_des3_cbc_none
= {
2556 ETYPE_DES3_CBC_NONE
,
2561 &keytype_des3_derived
,
2568 static struct encryption_type
*etypes
[] = {
2570 &enctype_des_cbc_crc
,
2571 &enctype_des_cbc_md4
,
2572 &enctype_des_cbc_md5
,
2573 &enctype_arcfour_hmac_md5
,
2574 &enctype_des3_cbc_md5
,
2575 &enctype_des3_cbc_sha1
,
2576 &enctype_old_des3_cbc_sha1
,
2578 &enctype_aes128_cts_hmac_sha1
,
2579 &enctype_aes256_cts_hmac_sha1
,
2581 &enctype_des_cbc_none
,
2582 &enctype_des_cfb64_none
,
2583 &enctype_des_pcbc_none
,
2584 &enctype_des3_cbc_none
2587 static unsigned num_etypes
= sizeof(etypes
) / sizeof(etypes
[0]);
2590 static struct encryption_type
*
2591 _find_enctype(krb5_enctype type
)
2594 for(i
= 0; i
< num_etypes
; i
++)
2595 if(etypes
[i
]->type
== type
)
2602 krb5_enctype_to_string(krb5_context context
,
2606 struct encryption_type
*e
;
2607 e
= _find_enctype(etype
);
2609 krb5_set_error_string (context
, "encryption type %d not supported",
2611 return KRB5_PROG_ETYPE_NOSUPP
;
2613 *string
= strdup(e
->name
);
2614 if(*string
== NULL
) {
2615 krb5_set_error_string(context
, "malloc: out of memory");
2622 krb5_string_to_enctype(krb5_context context
,
2624 krb5_enctype
*etype
)
2627 for(i
= 0; i
< num_etypes
; i
++)
2628 if(strcasecmp(etypes
[i
]->name
, string
) == 0){
2629 *etype
= etypes
[i
]->type
;
2632 krb5_set_error_string (context
, "encryption type %s not supported",
2634 return KRB5_PROG_ETYPE_NOSUPP
;
2638 krb5_enctype_to_keytype(krb5_context context
,
2640 krb5_keytype
*keytype
)
2642 struct encryption_type
*e
= _find_enctype(etype
);
2644 krb5_set_error_string (context
, "encryption type %d not supported",
2646 return KRB5_PROG_ETYPE_NOSUPP
;
2648 *keytype
= e
->keytype
->type
; /* XXX */
2654 krb5_keytype_to_enctype(krb5_context context
,
2655 krb5_keytype keytype
,
2656 krb5_enctype
*etype
)
2658 struct key_type
*kt
= _find_keytype(keytype
);
2659 krb5_warnx(context
, "krb5_keytype_to_enctype(%u)", keytype
);
2661 return KRB5_PROG_KEYTYPE_NOSUPP
;
2662 *etype
= kt
->best_etype
;
2668 krb5_keytype_to_enctypes (krb5_context context
,
2669 krb5_keytype keytype
,
2677 for (i
= num_etypes
- 1; i
>= 0; --i
) {
2678 if (etypes
[i
]->keytype
->type
== keytype
2679 && !(etypes
[i
]->flags
& F_PSEUDO
))
2682 ret
= malloc(n
* sizeof(*ret
));
2683 if (ret
== NULL
&& n
!= 0) {
2684 krb5_set_error_string(context
, "malloc: out of memory");
2688 for (i
= num_etypes
- 1; i
>= 0; --i
) {
2689 if (etypes
[i
]->keytype
->type
== keytype
2690 && !(etypes
[i
]->flags
& F_PSEUDO
))
2691 ret
[n
++] = etypes
[i
]->type
;
2699 * First take the configured list of etypes for `keytype' if available,
2700 * else, do `krb5_keytype_to_enctypes'.
2704 krb5_keytype_to_enctypes_default (krb5_context context
,
2705 krb5_keytype keytype
,
2712 if (keytype
!= KEYTYPE_DES
|| context
->etypes_des
== NULL
)
2713 return krb5_keytype_to_enctypes (context
, keytype
, len
, val
);
2715 for (n
= 0; context
->etypes_des
[n
]; ++n
)
2717 ret
= malloc (n
* sizeof(*ret
));
2718 if (ret
== NULL
&& n
!= 0) {
2719 krb5_set_error_string(context
, "malloc: out of memory");
2722 for (i
= 0; i
< n
; ++i
)
2723 ret
[i
] = context
->etypes_des
[i
];
2730 krb5_enctype_valid(krb5_context context
,
2733 return _find_enctype(etype
) != NULL
;
2736 /* if two enctypes have compatible keys */
2738 krb5_enctypes_compatible_keys(krb5_context context
,
2739 krb5_enctype etype1
,
2740 krb5_enctype etype2
)
2742 struct encryption_type
*e1
= _find_enctype(etype1
);
2743 struct encryption_type
*e2
= _find_enctype(etype2
);
2744 return e1
!= NULL
&& e2
!= NULL
&& e1
->keytype
== e2
->keytype
;
2748 derived_crypto(krb5_context context
,
2751 return (crypto
->et
->flags
& F_DERIVED
) != 0;
2755 special_crypto(krb5_context context
,
2758 return (crypto
->et
->flags
& F_SPECIAL
) != 0;
2761 #define CHECKSUMSIZE(C) ((C)->checksumsize)
2762 #define CHECKSUMTYPE(C) ((C)->type)
2764 static krb5_error_code
2765 encrypt_internal_derived(krb5_context context
,
2773 size_t sz
, block_sz
, checksum_sz
, total_sz
;
2775 unsigned char *p
, *q
;
2776 krb5_error_code ret
;
2777 struct key_data
*dkey
;
2778 const struct encryption_type
*et
= crypto
->et
;
2780 checksum_sz
= CHECKSUMSIZE(et
->keyed_checksum
);
2782 sz
= et
->confoundersize
+ len
;
2783 block_sz
= (sz
+ et
->padsize
- 1) &~ (et
->padsize
- 1); /* pad */
2784 total_sz
= block_sz
+ checksum_sz
;
2785 p
= calloc(1, total_sz
);
2787 krb5_set_error_string(context
, "malloc: out of memory");
2792 krb5_generate_random_block(q
, et
->confoundersize
); /* XXX */
2793 q
+= et
->confoundersize
;
2794 memcpy(q
, data
, len
);
2796 ret
= create_checksum(context
,
2799 INTEGRITY_USAGE(usage
),
2803 if(ret
== 0 && cksum
.checksum
.length
!= checksum_sz
) {
2804 free_Checksum (&cksum
);
2805 krb5_clear_error_string (context
);
2806 ret
= KRB5_CRYPTO_INTERNAL
;
2810 memcpy(p
+ block_sz
, cksum
.checksum
.data
, cksum
.checksum
.length
);
2811 free_Checksum (&cksum
);
2812 ret
= _get_derived_key(context
, crypto
, ENCRYPTION_USAGE(usage
), &dkey
);
2815 ret
= _key_schedule(context
, dkey
);
2819 krb5_crypto_debug(context
, 1, block_sz
, dkey
->key
);
2821 ret
= (*et
->encrypt
)(context
, dkey
, p
, block_sz
, 1, usage
, ivec
);
2825 result
->length
= total_sz
;
2828 memset(p
, 0, total_sz
);
2834 static krb5_error_code
2835 encrypt_internal(krb5_context context
,
2842 size_t sz
, block_sz
, checksum_sz
;
2844 unsigned char *p
, *q
;
2845 krb5_error_code ret
;
2846 const struct encryption_type
*et
= crypto
->et
;
2848 checksum_sz
= CHECKSUMSIZE(et
->checksum
);
2850 sz
= et
->confoundersize
+ checksum_sz
+ len
;
2851 block_sz
= (sz
+ et
->padsize
- 1) &~ (et
->padsize
- 1); /* pad */
2852 p
= calloc(1, block_sz
);
2854 krb5_set_error_string(context
, "malloc: out of memory");
2859 krb5_generate_random_block(q
, et
->confoundersize
); /* XXX */
2860 q
+= et
->confoundersize
;
2861 memset(q
, 0, checksum_sz
);
2863 memcpy(q
, data
, len
);
2865 ret
= create_checksum(context
,
2872 if(ret
== 0 && cksum
.checksum
.length
!= checksum_sz
) {
2873 krb5_clear_error_string (context
);
2874 free_Checksum(&cksum
);
2875 ret
= KRB5_CRYPTO_INTERNAL
;
2879 memcpy(p
+ et
->confoundersize
, cksum
.checksum
.data
, cksum
.checksum
.length
);
2880 free_Checksum(&cksum
);
2881 ret
= _key_schedule(context
, &crypto
->key
);
2885 krb5_crypto_debug(context
, 1, block_sz
, crypto
->key
.key
);
2887 ret
= (*et
->encrypt
)(context
, &crypto
->key
, p
, block_sz
, 1, 0, ivec
);
2889 memset(p
, 0, block_sz
);
2894 result
->length
= block_sz
;
2897 memset(p
, 0, block_sz
);
2902 static krb5_error_code
2903 encrypt_internal_special(krb5_context context
,
2911 struct encryption_type
*et
= crypto
->et
;
2912 size_t cksum_sz
= CHECKSUMSIZE(et
->checksum
);
2913 size_t sz
= len
+ cksum_sz
+ et
->confoundersize
;
2915 krb5_error_code ret
;
2919 krb5_set_error_string(context
, "malloc: out of memory");
2923 memset (p
, 0, cksum_sz
);
2925 krb5_generate_random_block(p
, et
->confoundersize
);
2926 p
+= et
->confoundersize
;
2927 memcpy (p
, data
, len
);
2928 ret
= (*et
->encrypt
)(context
, &crypto
->key
, tmp
, sz
, TRUE
, usage
, ivec
);
2935 result
->length
= sz
;
2939 static krb5_error_code
2940 decrypt_internal_derived(krb5_context context
,
2951 krb5_error_code ret
;
2952 struct key_data
*dkey
;
2953 struct encryption_type
*et
= crypto
->et
;
2956 checksum_sz
= CHECKSUMSIZE(et
->keyed_checksum
);
2957 if (len
< checksum_sz
) {
2958 krb5_clear_error_string (context
);
2959 return EINVAL
; /* XXX - better error code? */
2962 if (((len
- checksum_sz
) % et
->padsize
) != 0) {
2963 krb5_clear_error_string(context
);
2964 return KRB5_BAD_MSIZE
;
2968 if(len
!= 0 && p
== NULL
) {
2969 krb5_set_error_string(context
, "malloc: out of memory");
2972 memcpy(p
, data
, len
);
2976 ret
= _get_derived_key(context
, crypto
, ENCRYPTION_USAGE(usage
), &dkey
);
2981 ret
= _key_schedule(context
, dkey
);
2987 krb5_crypto_debug(context
, 0, len
, dkey
->key
);
2989 ret
= (*et
->encrypt
)(context
, dkey
, p
, len
, 0, usage
, ivec
);
2995 cksum
.checksum
.data
= p
+ len
;
2996 cksum
.checksum
.length
= checksum_sz
;
2997 cksum
.cksumtype
= CHECKSUMTYPE(et
->keyed_checksum
);
2999 ret
= verify_checksum(context
,
3001 INTEGRITY_USAGE(usage
),
3009 l
= len
- et
->confoundersize
;
3010 memmove(p
, p
+ et
->confoundersize
, l
);
3011 result
->data
= realloc(p
, l
);
3012 if(result
->data
== NULL
) {
3014 krb5_set_error_string(context
, "malloc: out of memory");
3021 static krb5_error_code
3022 decrypt_internal(krb5_context context
,
3029 krb5_error_code ret
;
3032 size_t checksum_sz
, l
;
3033 struct encryption_type
*et
= crypto
->et
;
3035 if ((len
% et
->padsize
) != 0) {
3036 krb5_clear_error_string(context
);
3037 return KRB5_BAD_MSIZE
;
3040 checksum_sz
= CHECKSUMSIZE(et
->checksum
);
3042 if(len
!= 0 && p
== NULL
) {
3043 krb5_set_error_string(context
, "malloc: out of memory");
3046 memcpy(p
, data
, len
);
3048 ret
= _key_schedule(context
, &crypto
->key
);
3054 krb5_crypto_debug(context
, 0, len
, crypto
->key
.key
);
3056 ret
= (*et
->encrypt
)(context
, &crypto
->key
, p
, len
, 0, 0, ivec
);
3061 ret
= krb5_data_copy(&cksum
.checksum
, p
+ et
->confoundersize
, checksum_sz
);
3066 memset(p
+ et
->confoundersize
, 0, checksum_sz
);
3067 cksum
.cksumtype
= CHECKSUMTYPE(et
->checksum
);
3068 ret
= verify_checksum(context
, NULL
, 0, p
, len
, &cksum
);
3069 free_Checksum(&cksum
);
3074 l
= len
- et
->confoundersize
- checksum_sz
;
3075 memmove(p
, p
+ et
->confoundersize
+ checksum_sz
, l
);
3076 result
->data
= realloc(p
, l
);
3077 if(result
->data
== NULL
) {
3079 krb5_set_error_string(context
, "malloc: out of memory");
3086 static krb5_error_code
3087 decrypt_internal_special(krb5_context context
,
3095 struct encryption_type
*et
= crypto
->et
;
3096 size_t cksum_sz
= CHECKSUMSIZE(et
->checksum
);
3097 size_t sz
= len
- cksum_sz
- et
->confoundersize
;
3099 krb5_error_code ret
;
3101 if ((len
% et
->padsize
) != 0) {
3102 krb5_clear_error_string(context
);
3103 return KRB5_BAD_MSIZE
;
3108 krb5_set_error_string(context
, "malloc: out of memory");
3111 memcpy(p
, data
, len
);
3113 ret
= (*et
->encrypt
)(context
, &crypto
->key
, p
, len
, FALSE
, usage
, ivec
);
3119 memmove (p
, p
+ cksum_sz
+ et
->confoundersize
, sz
);
3120 result
->data
= realloc(p
, sz
);
3121 if(result
->data
== NULL
) {
3123 krb5_set_error_string(context
, "malloc: out of memory");
3126 result
->length
= sz
;
3132 krb5_encrypt_ivec(krb5_context context
,
3140 if(derived_crypto(context
, crypto
))
3141 return encrypt_internal_derived(context
, crypto
, usage
,
3142 data
, len
, result
, ivec
);
3143 else if (special_crypto(context
, crypto
))
3144 return encrypt_internal_special (context
, crypto
, usage
,
3145 data
, len
, result
, ivec
);
3147 return encrypt_internal(context
, crypto
, data
, len
, result
, ivec
);
3151 krb5_encrypt(krb5_context context
,
3158 return krb5_encrypt_ivec(context
, crypto
, usage
, data
, len
, result
, NULL
);
3162 krb5_encrypt_EncryptedData(krb5_context context
,
3168 EncryptedData
*result
)
3170 result
->etype
= CRYPTO_ETYPE(crypto
);
3172 ALLOC(result
->kvno
, 1);
3173 *result
->kvno
= kvno
;
3175 result
->kvno
= NULL
;
3176 return krb5_encrypt(context
, crypto
, usage
, data
, len
, &result
->cipher
);
3180 krb5_decrypt_ivec(krb5_context context
,
3188 if(derived_crypto(context
, crypto
))
3189 return decrypt_internal_derived(context
, crypto
, usage
,
3190 data
, len
, result
, ivec
);
3191 else if (special_crypto (context
, crypto
))
3192 return decrypt_internal_special(context
, crypto
, usage
,
3193 data
, len
, result
, ivec
);
3195 return decrypt_internal(context
, crypto
, data
, len
, result
, ivec
);
3199 krb5_decrypt(krb5_context context
,
3206 return krb5_decrypt_ivec (context
, crypto
, usage
, data
, len
, result
,
3211 krb5_decrypt_EncryptedData(krb5_context context
,
3214 const EncryptedData
*e
,
3217 return krb5_decrypt(context
, crypto
, usage
,
3218 e
->cipher
.data
, e
->cipher
.length
, result
);
3221 /************************************************************
3223 ************************************************************/
3226 #include <openssl/rand.h>
3228 /* From openssl/crypto/rand/rand_lcl.h */
3229 #define ENTROPY_NEEDED 20
3231 seed_something(void)
3234 char buf
[1024], seedfile
[256];
3236 /* If there is a seed file, load it. But such a file cannot be trusted,
3237 so use 0 for the entropy estimate */
3238 if (RAND_file_name(seedfile
, sizeof(seedfile
))) {
3239 fd
= open(seedfile
, O_RDONLY
);
3241 read(fd
, buf
, sizeof(buf
));
3242 /* Use the full buffer anyway */
3243 RAND_add(buf
, sizeof(buf
), 0.0);
3249 /* Calling RAND_status() will try to use /dev/urandom if it exists so
3250 we do not have to deal with it. */
3251 if (RAND_status() != 1) {
3252 krb5_context context
;
3256 if (!krb5_init_context(&context
)) {
3257 p
= krb5_config_get_string(context
, NULL
, "libdefaults",
3258 "egd_socket", NULL
);
3260 RAND_egd_bytes(p
, ENTROPY_NEEDED
);
3261 krb5_free_context(context
);
3265 if (RAND_status() == 1) {
3266 /* Update the seed file */
3268 RAND_write_file(seedfile
);
3276 krb5_generate_random_block(void *buf
, size_t len
)
3278 static int rng_initialized
= 0;
3280 if (!rng_initialized
) {
3281 if (seed_something())
3282 krb5_abortx(NULL
, "Fatal: could not seed the random number generator");
3284 rng_initialized
= 1;
3286 RAND_bytes(buf
, len
);
3292 krb5_generate_random_block(void *buf
, size_t len
)
3294 des_cblock key
, out
;
3295 static des_cblock counter
;
3296 static des_key_schedule schedule
;
3298 static int initialized
= 0;
3301 des_new_random_key(&key
);
3302 des_set_key(&key
, schedule
);
3303 memset(&key
, 0, sizeof(key
));
3304 des_new_random_key(&counter
);
3307 des_ecb_encrypt(&counter
, &out
, schedule
, DES_ENCRYPT
);
3308 for(i
= 7; i
>=0; i
--)
3311 memcpy(buf
, out
, min(len
, sizeof(out
)));
3312 len
-= min(len
, sizeof(out
));
3313 buf
= (char*)buf
+ sizeof(out
);
3319 DES3_postproc(krb5_context context
,
3320 unsigned char *k
, size_t len
, struct key_data
*key
)
3322 unsigned char x
[24];
3325 memset(x
, 0, sizeof(x
));
3326 for (i
= 0; i
< 3; ++i
) {
3329 for (j
= 0; j
< 7; ++j
) {
3330 unsigned char b
= k
[7 * i
+ j
];
3335 for (j
= 6; j
>= 0; --j
) {
3336 foo
|= k
[7 * i
+ j
] & 1;
3341 k
= key
->key
->keyvalue
.data
;
3343 memset(x
, 0, sizeof(x
));
3344 if (key
->schedule
) {
3345 krb5_free_data(context
, key
->schedule
);
3346 key
->schedule
= NULL
;
3348 des_set_odd_parity((des_cblock
*)k
);
3349 des_set_odd_parity((des_cblock
*)(k
+ 8));
3350 des_set_odd_parity((des_cblock
*)(k
+ 16));
3353 static krb5_error_code
3354 derive_key(krb5_context context
,
3355 struct encryption_type
*et
,
3356 struct key_data
*key
,
3357 const void *constant
,
3361 unsigned int nblocks
= 0, i
;
3362 krb5_error_code ret
= 0;
3364 struct key_type
*kt
= et
->keytype
;
3365 ret
= _key_schedule(context
, key
);
3368 if(et
->blocksize
* 8 < kt
->bits
||
3369 len
!= et
->blocksize
) {
3370 nblocks
= (kt
->bits
+ et
->blocksize
* 8 - 1) / (et
->blocksize
* 8);
3371 k
= malloc(nblocks
* et
->blocksize
);
3373 krb5_set_error_string(context
, "malloc: out of memory");
3376 _krb5_n_fold(constant
, len
, k
, et
->blocksize
);
3377 for(i
= 0; i
< nblocks
; i
++) {
3379 memcpy(k
+ i
* et
->blocksize
,
3380 k
+ (i
- 1) * et
->blocksize
,
3382 (*et
->encrypt
)(context
, key
, k
+ i
* et
->blocksize
, et
->blocksize
,
3386 /* this case is probably broken, but won't be run anyway */
3387 void *c
= malloc(len
);
3388 size_t res_len
= (kt
->bits
+ 7) / 8;
3390 if(len
!= 0 && c
== NULL
) {
3391 krb5_set_error_string(context
, "malloc: out of memory");
3394 memcpy(c
, constant
, len
);
3395 (*et
->encrypt
)(context
, key
, c
, len
, 1, 0, NULL
);
3396 k
= malloc(res_len
);
3397 if(res_len
!= 0 && k
== NULL
) {
3399 krb5_set_error_string(context
, "malloc: out of memory");
3402 _krb5_n_fold(c
, len
, k
, res_len
);
3406 /* XXX keytype dependent post-processing */
3409 DES3_postproc(context
, k
, nblocks
* et
->blocksize
, key
);
3412 case KEYTYPE_AES128
:
3413 case KEYTYPE_AES256
:
3414 memcpy(key
->key
->keyvalue
.data
, k
, key
->key
->keyvalue
.length
);
3416 #endif /* ENABLE_AES */
3418 krb5_set_error_string(context
,
3419 "derive_key() called with unknown keytype (%u)",
3421 ret
= KRB5_CRYPTO_INTERNAL
;
3424 memset(k
, 0, nblocks
* et
->blocksize
);
3429 static struct key_data
*
3430 _new_derived_key(krb5_crypto crypto
, unsigned usage
)
3432 struct key_usage
*d
= crypto
->key_usage
;
3433 d
= realloc(d
, (crypto
->num_key_usage
+ 1) * sizeof(*d
));
3436 crypto
->key_usage
= d
;
3437 d
+= crypto
->num_key_usage
++;
3438 memset(d
, 0, sizeof(*d
));
3444 krb5_derive_key(krb5_context context
,
3445 const krb5_keyblock
*key
,
3447 const void *constant
,
3448 size_t constant_len
,
3449 krb5_keyblock
**derived_key
)
3451 krb5_error_code ret
;
3452 struct encryption_type
*et
;
3455 et
= _find_enctype (etype
);
3457 krb5_set_error_string(context
, "encryption type %d not supported",
3459 return KRB5_PROG_ETYPE_NOSUPP
;
3462 ret
= krb5_copy_keyblock(context
, key
, derived_key
);
3466 d
.key
= *derived_key
;
3468 ret
= derive_key(context
, et
, &d
, constant
, constant_len
);
3471 ret
= krb5_copy_keyblock(context
, d
.key
, derived_key
);
3475 static krb5_error_code
3476 _get_derived_key(krb5_context context
,
3479 struct key_data
**key
)
3483 unsigned char constant
[5];
3485 for(i
= 0; i
< crypto
->num_key_usage
; i
++)
3486 if(crypto
->key_usage
[i
].usage
== usage
) {
3487 *key
= &crypto
->key_usage
[i
].key
;
3490 d
= _new_derived_key(crypto
, usage
);
3492 krb5_set_error_string(context
, "malloc: out of memory");
3495 krb5_copy_keyblock(context
, crypto
->key
.key
, &d
->key
);
3496 _krb5_put_int(constant
, usage
, 5);
3497 derive_key(context
, crypto
->et
, d
, constant
, sizeof(constant
));
3504 krb5_crypto_init(krb5_context context
,
3505 const krb5_keyblock
*key
,
3507 krb5_crypto
*crypto
)
3509 krb5_error_code ret
;
3511 if(*crypto
== NULL
) {
3512 krb5_set_error_string(context
, "malloc: out of memory");
3515 if(etype
== ETYPE_NULL
)
3516 etype
= key
->keytype
;
3517 (*crypto
)->et
= _find_enctype(etype
);
3518 if((*crypto
)->et
== NULL
) {
3520 krb5_set_error_string (context
, "encryption type %d not supported",
3522 return KRB5_PROG_ETYPE_NOSUPP
;
3524 if((*crypto
)->et
->keytype
->size
!= key
->keyvalue
.length
) {
3526 krb5_set_error_string (context
, "encryption key has bad length");
3527 return KRB5_BAD_KEYSIZE
;
3529 ret
= krb5_copy_keyblock(context
, key
, &(*crypto
)->key
.key
);
3534 (*crypto
)->key
.schedule
= NULL
;
3535 (*crypto
)->num_key_usage
= 0;
3536 (*crypto
)->key_usage
= NULL
;
3541 free_key_data(krb5_context context
, struct key_data
*key
)
3543 krb5_free_keyblock(context
, key
->key
);
3545 memset(key
->schedule
->data
, 0, key
->schedule
->length
);
3546 krb5_free_data(context
, key
->schedule
);
3551 free_key_usage(krb5_context context
, struct key_usage
*ku
)
3553 free_key_data(context
, &ku
->key
);
3557 krb5_crypto_destroy(krb5_context context
,
3562 for(i
= 0; i
< crypto
->num_key_usage
; i
++)
3563 free_key_usage(context
, &crypto
->key_usage
[i
]);
3564 free(crypto
->key_usage
);
3565 free_key_data(context
, &crypto
->key
);
3571 krb5_crypto_getblocksize(krb5_context context
,
3575 *blocksize
= crypto
->et
->blocksize
;
3580 krb5_string_to_key_derived(krb5_context context
,
3586 struct encryption_type
*et
= _find_enctype(etype
);
3587 krb5_error_code ret
;
3589 size_t keylen
= et
->keytype
->bits
/ 8;
3593 krb5_set_error_string (context
, "encryption type %d not supported",
3595 return KRB5_PROG_ETYPE_NOSUPP
;
3598 if(kd
.key
== NULL
) {
3599 krb5_set_error_string (context
, "malloc: out of memory");
3602 ret
= krb5_data_alloc(&kd
.key
->keyvalue
, et
->keytype
->size
);
3607 kd
.key
->keytype
= etype
;
3608 tmp
= malloc (keylen
);
3610 krb5_free_keyblock(context
, kd
.key
);
3611 krb5_set_error_string (context
, "malloc: out of memory");
3614 _krb5_n_fold(str
, len
, tmp
, keylen
);
3616 DES3_postproc (context
, tmp
, keylen
, &kd
); /* XXX */
3617 memset(tmp
, 0, keylen
);
3619 ret
= derive_key(context
,
3622 "kerberos", /* XXX well known constant */
3623 strlen("kerberos"));
3624 ret
= krb5_copy_keyblock_contents(context
, kd
.key
, key
);
3625 free_key_data(context
, &kd
);
3630 wrapped_length (krb5_context context
,
3634 struct encryption_type
*et
= crypto
->et
;
3635 size_t padsize
= et
->padsize
;
3638 res
= et
->confoundersize
+ et
->checksum
->checksumsize
+ data_len
;
3639 res
= (res
+ padsize
- 1) / padsize
* padsize
;
3644 wrapped_length_dervied (krb5_context context
,
3648 struct encryption_type
*et
= crypto
->et
;
3649 size_t padsize
= et
->padsize
;
3652 res
= et
->confoundersize
+ data_len
;
3653 res
= (res
+ padsize
- 1) / padsize
* padsize
;
3654 res
+= et
->checksum
->checksumsize
;
3659 * Return the size of an encrypted packet of length `data_len'
3663 krb5_get_wrapped_length (krb5_context context
,
3667 if (derived_crypto (context
, crypto
))
3668 return wrapped_length_dervied (context
, crypto
, data_len
);
3670 return wrapped_length (context
, crypto
, data_len
);
3675 static krb5_error_code
3676 krb5_get_keyid(krb5_context context
,
3681 unsigned char tmp
[16];
3684 MD5_Update (&md5
, key
->keyvalue
.data
, key
->keyvalue
.length
);
3685 MD5_Final (tmp
, &md5
);
3686 *keyid
= (tmp
[12] << 24) | (tmp
[13] << 16) | (tmp
[14] << 8) | tmp
[15];
3691 krb5_crypto_debug(krb5_context context
,
3698 krb5_get_keyid(context
, key
, &keyid
);
3699 krb5_enctype_to_string(context
, key
->keytype
, &kt
);
3700 krb5_warnx(context
, "%s %lu bytes with key-id %#x (%s)",
3701 encrypt
? "encrypting" : "decrypting",
3708 #endif /* CRYPTO_DEBUG */
3716 krb5_context context
;
3721 unsigned usage
= ENCRYPTION_USAGE(3);
3722 krb5_error_code ret
;
3724 ret
= krb5_init_context(&context
);
3726 errx (1, "krb5_init_context failed: %d", ret
);
3728 key
.keytype
= ETYPE_NEW_DES3_CBC_SHA1
;
3729 key
.keyvalue
.data
= "\xb3\x85\x58\x94\xd9\xdc\x7c\xc8"
3730 "\x25\xe9\x85\xab\x3e\xb5\xfb\x0e"
3731 "\xc8\xdf\xab\x26\x86\x64\x15\x25";
3732 key
.keyvalue
.length
= 24;
3734 krb5_crypto_init(context
, &key
, 0, &crypto
);
3736 d
= _new_derived_key(crypto
, usage
);
3739 krb5_copy_keyblock(context
, crypto
->key
.key
, &d
->key
);
3740 _krb5_put_int(constant
, usage
, 4);
3741 derive_key(context
, crypto
->et
, d
, constant
, sizeof(constant
));
3745 krb5_context context
;
3749 krb5_error_code ret
;
3752 char *data
= "what do ya want for nothing?";
3754 ret
= krb5_init_context(&context
);
3756 errx (1, "krb5_init_context failed: %d", ret
);
3758 key
.keytype
= ETYPE_NEW_DES3_CBC_SHA1
;
3759 key
.keyvalue
.data
= "Jefe";
3760 /* "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
3761 "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"; */
3762 key
.keyvalue
.length
= 4;
3764 d
= calloc(1, sizeof(*d
));
3767 res
.checksum
.length
= 20;
3768 res
.checksum
.data
= malloc(res
.checksum
.length
);
3769 SP_HMAC_SHA1_checksum(context
, d
, data
, 28, &res
);