2 * Copyright (c) 1995, 1996, 1997, 2002 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 * Copyright 1992, 2002 by the Massachusetts Institute of Technology.
35 * All Rights Reserved.
37 * Export of this software from the United States of America may
38 * require a specific license from the United States Government.
39 * It is the responsibility of any person or organization contemplating
40 * export to obtain such a license before exporting.
42 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
43 * distribute this software and its documentation for any purpose and
44 * without fee is hereby granted, provided that the above copyright
45 * notice appear in all copies and that both that copyright notice and
46 * this permission notice appear in supporting documentation, and that
47 * the name of M.I.T. not be used in advertising or publicity pertaining
48 * to distribution of the software without specific, written prior
49 * permission. Furthermore if you modify this software you must label
50 * your software as modified software and not distribute it in such a
51 * fashion that it might be confused with the original M.I.T. software.
52 * M.I.T. makes no representations about the suitability of
53 * this software for any purpose. It is provided "as is" without express
54 * or implied warranty.
57 #include <afsconfig.h>
58 #include <afs/param.h>
60 #ifdef IGNORE_SOME_GCC_WARNINGS
61 # pragma GCC diagnostic warning "-Wimplicit-function-declaration"
65 #include <sys/types.h>
69 #include <netinet/in.h>
75 #include <des_prototypes.h>
76 #include "lifetimes.h"
79 #include "v5gen-rewrite.h"
88 * Principal conversion Taken from src/lib/krb5/krb/conv_princ from MIT Kerberos. If you
89 * find a need to change the services here, please consider opening a
90 * bug with MIT by sending mail to krb5-bugs@mit.edu.
93 extern afs_int32
des_cbc_encrypt(void * in
, void * out
,
95 des_key_schedule key
, des_cblock
*iv
,
97 extern int des_key_sched(des_cblock k
, des_key_schedule schedule
);
106 #define DO_REALM_CONVERSION 0x00000001
109 * Kadmin doesn't do realm conversion because it's currently
110 * kadmin/REALM.NAME. Zephyr doesn't because it's just zephyr/zephyr.
112 * "Realm conversion" is a bit of a misnomer; really, the v5 name is
113 * using a FQDN or something that looks like it, where the v4 name is
114 * just using the first label. Sometimes that second principal name
115 * component is a hostname, sometimes the realm name, sometimes it's
118 * This list should probably be more configurable, and more than
119 * likely on a per-realm basis, so locally-defined services can be
122 static const struct krb_convert sconv_list
[] = {
123 /* Realm conversion, Change service name */
124 #define RC(V5NAME,V4NAME) { V5NAME, V4NAME, DO_REALM_CONVERSION, sizeof(V5NAME)-1 }
125 /* Realm conversion */
126 #define R(NAME) { NAME, NAME, DO_REALM_CONVERSION, sizeof(NAME)-1 }
127 /* No Realm conversion */
128 #define NR(NAME) { NAME, NAME, 0, sizeof(NAME)-1 }
179 krb5_des_decrypt(struct ktc_encryptionKey
*, int, void *, size_t, void *,
181 static int rxkad_derive_des_key(const void *, size_t,
182 struct ktc_encryptionKey
*);
183 static int compress_parity_bits(void *, size_t *);
184 static void hmac_md5_iov(const void *, size_t, const struct iovec
*,
185 unsigned int, void *);
189 tkt_DecodeTicket5(char *ticket
, afs_int32 ticket_len
,
190 int (*get_key
) (void *, int, struct ktc_encryptionKey
*),
191 char *get_key_rock
, int serv_kvno
, char *name
, char *inst
,
192 char *cell
, struct ktc_encryptionKey
*session_key
, afs_int32
* host
,
193 afs_uint32
* start
, afs_uint32
* end
, afs_int32 disableCheckdot
,
194 rxkad_alt_decrypt_func alt_decrypt
)
196 char plain
[MAXKRB5TICKETLEN
];
197 struct ktc_encryptionKey serv_key
;
198 Ticket t5
; /* Must free */
199 EncTicketPart decr_part
; /* Must free */
201 size_t siz
, plainsiz
;
203 char *v5_comp0
, *v5_comp1
, *c
;
204 const struct krb_convert
*p
;
206 memset(&t5
, 0, sizeof(t5
));
207 memset(&decr_part
, 0, sizeof(decr_part
));
212 return RXKADBADTICKET
; /* no ticket */
214 if (serv_kvno
== RXKAD_TKT_TYPE_KERBEROS_V5
) {
215 code
= decode_Ticket((unsigned char *)ticket
, ticket_len
, &t5
, &siz
);
222 code
= decode_EncryptedData((unsigned char *)ticket
, ticket_len
, &t5
.enc_part
, &siz
);
227 /* If kvno is null, it's probably not included because it was kvno==0
229 if (t5
.enc_part
.kvno
== NULL
) {
232 v5_serv_kvno
= *t5
.enc_part
.kvno
;
236 if (t5
.enc_part
.cipher
.length
> sizeof(plain
))
238 switch (t5
.enc_part
.etype
) {
239 case ETYPE_DES_CBC_CRC
:
240 case ETYPE_DES_CBC_MD4
:
241 case ETYPE_DES_CBC_MD5
:
242 /* Check that the key type really fit into 8 bytes */
243 if (t5
.enc_part
.cipher
.length
% 8 != 0)
246 code
= (*get_key
) (get_key_rock
, v5_serv_kvno
, &serv_key
);
250 /* Decrypt data here, save in plain, assume it will shrink */
252 krb5_des_decrypt(&serv_key
, t5
.enc_part
.etype
,
253 t5
.enc_part
.cipher
.data
,
254 t5
.enc_part
.cipher
.length
, plain
, &plainsiz
);
259 if (alt_decrypt
!= NULL
) {
260 plainsiz
= sizeof(plain
);
261 code
= alt_decrypt(v5_serv_kvno
, t5
.enc_part
.etype
,
262 t5
.enc_part
.cipher
.data
,
263 t5
.enc_part
.cipher
.length
, plain
, &plainsiz
);
271 code
= decode_EncTicketPart((unsigned char *)plain
, plainsiz
, &decr_part
, &siz
);
275 /* Extract realm and principal */
276 strncpy(cell
, decr_part
.crealm
, MAXKTCNAMELEN
);
277 cell
[MAXKTCNAMELEN
- 1] = '\0';
279 switch (decr_part
.cname
.name_string
.len
) {
281 v5_comp0
= decr_part
.cname
.name_string
.val
[0];
282 v5_comp1
= decr_part
.cname
.name_string
.val
[1];
285 if (strcmp(p
->v5_str
, v5_comp0
) == 0) {
287 * It is, so set the new name now, and chop off
288 * instance's domain name if requested.
290 strncpy(name
, p
->v4_str
, MAXKTCNAMELEN
);
291 name
[MAXKTCNAMELEN
- 1] = '\0';
292 if (p
->flags
& DO_REALM_CONVERSION
) {
293 c
= strchr(v5_comp1
, '.');
294 if (!c
|| (c
- v5_comp1
) >= MAXKTCNAMELEN
- 1)
296 strncpy(inst
, v5_comp1
, c
- v5_comp1
);
297 inst
[c
- v5_comp1
] = '\0';
305 strncpy(inst
, decr_part
.cname
.name_string
.val
[1], MAXKTCNAMELEN
);
306 inst
[MAXKTCNAMELEN
- 1] = '\0';
307 strncpy(name
, decr_part
.cname
.name_string
.val
[0], MAXKTCNAMELEN
);
308 name
[MAXKTCNAMELEN
- 1] = '\0';
312 strncpy(name
, decr_part
.cname
.name_string
.val
[0], MAXKTCNAMELEN
);
313 name
[MAXKTCNAMELEN
- 1] = '\0';
319 if (!disableCheckdot
) {
321 * If the first part of the name_string contains a dot, punt since
322 * then we can't see the diffrence between the kerberos 5
323 * principals foo.root and foo/root later in the fileserver.
325 if (strchr(decr_part
.cname
.name_string
.val
[0], '.') != NULL
)
329 /* Verify that decr_part.key is of right type */
330 if (tkt_DeriveDesKey(decr_part
.key
.keytype
, decr_part
.key
.keyvalue
.data
,
331 decr_part
.key
.keyvalue
.length
, session_key
) != 0)
333 /* Check lifetimes and host addresses, flags etc */
335 time_t now
= time(0); /* Use fast time package instead??? */
336 *start
= decr_part
.authtime
;
337 if (decr_part
.starttime
)
338 *start
= *decr_part
.starttime
;
340 if (*start
- now
> CLOCK_SKEW
|| decr_part
.flags
.invalid
)
343 if (decr_part
.flags
.invalid
)
346 if (now
> decr_part
.endtime
)
348 *end
= decr_part
.endtime
;
352 if (serv_kvno
== RXKAD_TKT_TYPE_KERBEROS_V5
)
355 free_EncryptedData(&t5
.enc_part
);
356 free_EncTicketPart(&decr_part
);
357 memset(&serv_key
, 0, sizeof(serv_key
));
361 code
= RXKADUNKNOWNKEY
;
370 code
= RXKADBADTICKET
;
376 verify_checksum_md4(void *data
, size_t len
,
377 void *cksum
, size_t cksumsz
,
378 struct ktc_encryptionKey
*key
)
381 unsigned char tmp
[16];
384 MD4_Update(&md4
, data
, len
);
385 MD4_Final(tmp
, &md4
);
387 if (memcmp(tmp
, cksum
, cksumsz
) != 0)
393 verify_checksum_md5(void *data
, size_t len
,
394 void *cksum
, size_t cksumsz
,
395 struct ktc_encryptionKey
*key
)
398 unsigned char tmp
[16];
401 MD5_Update(&md5
, data
, len
);
402 MD5_Final(tmp
, &md5
);
404 if (memcmp(tmp
, cksum
, cksumsz
) != 0)
410 verify_checksum_crc(void *data
, size_t len
, void *cksum
, size_t cksumsz
,
411 struct ktc_encryptionKey
*key
)
416 _rxkad_crc_init_table();
417 crc
= _rxkad_crc_update(data
, len
, 0);
419 r
[1] = (crc
>> 8) & 0xff;
420 r
[2] = (crc
>> 16) & 0xff;
421 r
[3] = (crc
>> 24) & 0xff;
423 if (memcmp(cksum
, r
, 4) != 0)
430 krb5_des_decrypt(struct ktc_encryptionKey
*key
, int etype
, void *in
,
431 size_t insz
, void *out
, size_t * outsz
)
433 int (*cksum_func
) (void *, size_t, void *, size_t,
434 struct ktc_encryptionKey
*);
439 int ret
= 1; /* failure */
443 des_key_sched(ktc_to_cblock(key
), (struct des_ks_struct
*)&s
);
445 #define CONFOUNDERSZ 8
448 case ETYPE_DES_CBC_CRC
:
449 memcpy(&ivec
, key
, sizeof(ivec
));
451 cksum_func
= verify_checksum_crc
;
453 case ETYPE_DES_CBC_MD4
:
454 memset(&ivec
, 0, sizeof(ivec
));
456 cksum_func
= verify_checksum_md4
;
458 case ETYPE_DES_CBC_MD5
:
459 memset(&ivec
, 0, sizeof(ivec
));
461 cksum_func
= verify_checksum_md5
;
467 des_cbc_encrypt(in
, out
, insz
, s
, &ivec
, 0);
469 memcpy(cksum
, (char *)out
+ CONFOUNDERSZ
, cksumsz
);
470 memset((char *)out
+ CONFOUNDERSZ
, 0, cksumsz
);
473 ret
= (*cksum_func
) (out
, insz
, cksum
, cksumsz
, key
);
475 *outsz
= insz
- CONFOUNDERSZ
- cksumsz
;
476 memmove(out
, (char *)out
+ CONFOUNDERSZ
+ cksumsz
, *outsz
);
482 * Use NIST SP800-108 with HMAC(MD5) in counter mode as the PRF to derive a
483 * des key from another type of key.
485 * L is 64, as we take 64 random bits and turn them into a 56-bit des key.
486 * The output of hmac_md5 is 128 bits; we take the first 64 only, so n
487 * properly should be 1. However, we apply a slight variation due to the
488 * possibility of producing a weak des key. If the output key is weak, do NOT
489 * simply correct it, instead, the counter is advanced and the next output
490 * used. As such, we code so as to have n be the full 255 permitted by our
491 * encoding of the counter i in an 8-bit field. L itself is encoded as a
492 * 32-bit field, big-endian. We use the constant string "rxkad" as a label
493 * for this key derivation, the standard NUL byte separator, and omit a
494 * key-derivation context. The input key is unique to the krb5 service ticket,
495 * which is unlikely to be used in an other location. If it is used in such
496 * a fashion, both locations will derive the same des key from the PRF, but
497 * this is no different from if a krb5 des key had been used in the same way,
498 * as traditional krb5 rxkad uses the ticket session key directly as the token
502 rxkad_derive_des_key(const void *in
, size_t insize
,
503 struct ktc_encryptionKey
*out
)
506 char Lbuf
[4]; /* bits of output, as 32 bit word, MSB first */
516 iov
[0].iov_base
= &i
;
518 iov
[1].iov_base
= "rxkad";
519 iov
[1].iov_len
= strlen("rxkad") + 1; /* includes label and separator */
520 iov
[2].iov_base
= Lbuf
;
523 /* stop when 8 bit counter wraps to 0 */
524 for (i
= 1; i
; i
++) {
525 hmac_md5_iov(in
, insize
, iov
, 3, tmp
);
526 memcpy(ktmp
, tmp
, 8);
527 des_fixup_key_parity(ktmp
);
528 if (!des_is_weak_key(ktmp
)) {
529 memcpy(out
->data
, ktmp
, 8);
537 * This is the inverse of the random-to-key for 3des specified in
538 * rfc3961, converting blocks of 8 bytes to blocks of 7 bytes by distributing
539 * the bits of each 8th byte as the lsb of the previous 7 bytes.
542 compress_parity_bits(void *buffer
, size_t *bufsiz
)
544 unsigned char *cb
, tmp
;
547 if (*bufsiz
% 8 != 0)
549 cb
= (unsigned char *)buffer
;
551 for (i
= 0; i
< nk
; i
++) {
552 tmp
= cb
[8 * i
+ 7] >> 1;
553 for (j
= 0; j
< 7; j
++) {
554 cb
[8 * i
+ j
] &= 0xfe;
555 cb
[8 * i
+ j
] |= tmp
& 0x1;
559 for (i
= 1; i
< nk
; i
++)
560 memmove(cb
+ 7 * i
, cb
+ 8 * i
, 7);
565 /* HMAC: Keyed-Hashing for Message Authentication, using MD5 as the hash.
568 * The constants 64 and 16 are the input block size and output length,
569 * respectively, of md5.
572 hmac_md5_iov(const void *key
, size_t ks
,
573 const struct iovec
*data
, unsigned int niov
, void *output
)
576 const unsigned char *kp
;
578 unsigned char tmp
[16], tmpk
[16], i_pad
[64], o_pad
[64];
581 MD5_Update(&md5
, key
, ks
);
582 MD5_Final(tmpk
, &md5
);
587 for (i
= 0; i
< ks
; i
++)
588 i_pad
[i
] = kp
[i
] ^ 0x36;
589 memset(i_pad
+ ks
, 0x36, 64 - ks
);
591 MD5_Update(&md5
, i_pad
, 64);
592 for (i
= 0; i
< niov
; i
++)
593 MD5_Update(&md5
, data
[i
].iov_base
, data
[i
].iov_len
);
594 MD5_Final(tmp
, &md5
);
595 for (i
= 0; i
< ks
; i
++)
596 o_pad
[i
] = kp
[i
] ^ 0x5c;
597 memset(o_pad
+ ks
, 0x5c, 64 - ks
);
599 MD5_Update(&md5
, o_pad
, 64);
600 MD5_Update(&md5
, tmp
, 16);
601 MD5_Final(output
, &md5
);
605 * Enctype-specific knowledge about how to derive a des key from a given
606 * key. If given a des key, use it directly; otherwise, perform any
607 * parity fixup that may be needed and pass through to the hmad-md5 bits.
610 tkt_DeriveDesKey(int enctype
, void *keydata
, size_t keylen
,
611 struct ktc_encryptionKey
*output
)
614 case ETYPE_DES_CBC_CRC
:
615 case ETYPE_DES_CBC_MD4
:
616 case ETYPE_DES_CBC_MD5
:
620 /* Extract session key */
621 memcpy(output
, keydata
, 8);
635 /*In order to become a "Cryptographic Key" as specified in
636 * SP800-108, it must be indistinguishable from a random bitstring. */
637 case ETYPE_DES3_CBC_MD5
:
638 case ETYPE_OLD_DES3_CBC_SHA1
:
639 case ETYPE_DES3_CBC_SHA1
:
640 if (compress_parity_bits(keydata
, &keylen
))
648 if (rxkad_derive_des_key(keydata
, keylen
, output
) != 0)