2 * Copyright (c) 1995-2003 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Portions Copyright (c) 2013-2014 Carnegie Mellon University
9 * Portions Copyright (c) 2013 by the Massachusetts Institute of Technology
10 * All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
23 * 3. Neither the name of the Institute nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 #include "kafs_locl.h"
42 static int rxkad_derive_des_key(const void *, size_t, char[8]);
43 static int compress_parity_bits(void *, size_t *);
46 * Use NIST SP800-108 with HMAC(MD5) in counter mode as the PRF to derive a
47 * des key from another type of key.
49 * L is 64, as we take 64 random bits and turn them into a 56-bit des key.
50 * The output of hmac_md5 is 128 bits; we take the first 64 only, so n
51 * properly should be 1. However, we apply a slight variation due to the
52 * possibility of producing a weak des key. If the output key is weak, do NOT
53 * simply correct it, instead, the counter is advanced and the next output
54 * used. As such, we code so as to have n be the full 255 permitted by our
55 * encoding of the counter i in an 8-bit field. L itself is encoded as a
56 * 32-bit field, big-endian. We use the constant string "rxkad" as a label
57 * for this key derivation, the standard NUL byte separator, and omit a
58 * key-derivation context. The input key is unique to the krb5 service ticket,
59 * which is unlikely to be used in an other location. If it is used in such
60 * a fashion, both locations will derive the same des key from the PRF, but
61 * this is no different from if a krb5 des key had been used in the same way,
62 * as traditional krb5 rxkad uses the ticket session key directly as the token
65 * @param[in] in pointer to input key data
66 * @param[in] insize length of input key data
67 * @param[out] out 8-byte buffer to hold the derived key
69 * @return Returns 0 to indicate success, or an error code.
71 * @retval KRB5DES_WEAK_KEY Successive derivation attempts with all
72 * 255 possible counter values each produced weak DES keys. This input
73 * cannot be used to produce a usable key.
76 rxkad_derive_des_key(const void *in
, size_t insize
, char out
[8])
79 static unsigned char label
[] = "rxkad";
80 /* bits of output, as 32 bit word, MSB first */
81 static unsigned char Lbuf
[4] = { 0, 0, 0, 64 };
82 /* only needs to be 16 for md5, but lets be sure it fits */
83 unsigned char tmp
[64];
88 /* stop when 8 bit counter wraps to 0 */
91 HMAC_Init_ex(&mctx
, in
, insize
, EVP_md5(), NULL
);
92 HMAC_Update(&mctx
, &i
, 1);
93 HMAC_Update(&mctx
, label
, sizeof(label
)); /* includes label and separator */
94 HMAC_Update(&mctx
, Lbuf
, 4);
96 HMAC_Final(&mctx
, tmp
, &mdsize
);
98 DES_set_odd_parity(&ktmp
);
99 if (!DES_is_weak_key(&ktmp
)) {
100 memcpy(out
, ktmp
, 8);
104 return KRB5DES_WEAK_KEY
;
108 * This is the inverse of the random-to-key for 3des specified in
109 * rfc3961, converting blocks of 8 bytes to blocks of 7 bytes by distributing
110 * the bits of each 8th byte as the lsb of the previous 7 bytes.
112 * @param[in,out] buffer Buffer containing the key to be converted
113 * @param[in,out] bufsiz Points to the size of the key data. On
114 * return, this is updated to reflect the size of the compressed data.
116 * @return Returns 0 to indicate success, or an error code.
118 * @retval KRB5_BAD_KEYSIZE The key size was not a multiple of 8 bytes.
121 compress_parity_bits(void *buffer
, size_t *bufsiz
)
123 unsigned char *cb
, tmp
;
126 if (*bufsiz
% 8 != 0)
127 return KRB5_BAD_KEYSIZE
;
128 cb
= (unsigned char *)buffer
;
130 for (i
= 0; i
< nk
; i
++) {
131 tmp
= cb
[8 * i
+ 7] >> 1;
132 for (j
= 0; j
< 7; j
++) {
133 cb
[8 * i
+ j
] &= 0xfe;
134 cb
[8 * i
+ j
] |= tmp
& 0x1;
138 for (i
= 1; i
< nk
; i
++)
139 memmove(cb
+ 7 * i
, cb
+ 8 * i
, 7);
145 * Derive a DES key for use with rxkad and fcrypt from a given Kerberos
146 * key of (almost) any type. This function encodes enctype-specific
147 * knowledge about how to derive a DES key from a given key type.
148 * If given a des key, use it directly; otherwise, perform any parity
149 * fixup that may be needed and pass through to the hmad-md5 bits.
151 * @param[in] enctype Kerberos enctype of the input key
152 * @param[in] keydata Input key data
153 * @param[in] keylen Size of input key data
154 * @param[out] output 8-byte buffer to hold the derived key
156 * @return Returns 0 to indicate success, or an error code.
158 * @retval KRB5_PROG_ETYPE_NOSUPP The enctype is one for which rxkad-kdf
159 * is not supported. This includes several reserved enctypes, enctype
160 * values used in PKINIT to stand for CMS algorithm identifiers, and all
161 * private-use (negative) enctypes.
163 * @retval KRB5_BAD_KEYSIZE The key size was not a multiple of 8 bytes
164 * (for 3DES key types), exactly 8 bytes (for DES key types), or at least
165 * 8 bytes (for other key types).
167 * @retval KRB5DES_WEAK_KEY Successive derivation attempts with all
168 * 255 possible counter values each produced weak DES keys. This input
169 * cannot be used to produce a usable key.
172 _kafs_derive_des_key(krb5_enctype enctype
, void *keydata
, size_t keylen
,
177 switch ((int)enctype
) {
178 case ETYPE_DES_CBC_CRC
:
179 case ETYPE_DES_CBC_MD4
:
180 case ETYPE_DES_CBC_MD5
:
182 return KRB5_BAD_KEYSIZE
;
184 /* Extract session key */
185 memcpy(output
, keydata
, 8);
198 return KRB5_PROG_ETYPE_NOSUPP
;
199 /*In order to become a "Cryptographic Key" as specified in
200 * SP800-108, it must be indistinguishable from a random bitstring. */
201 case ETYPE_DES3_CBC_MD5
:
202 case ETYPE_OLD_DES3_CBC_SHA1
:
203 case ETYPE_DES3_CBC_SHA1
:
204 ret
= compress_parity_bits(keydata
, &keylen
);
210 return KRB5_PROG_ETYPE_NOSUPP
;
212 return KRB5_BAD_KEYSIZE
;
213 ret
= rxkad_derive_des_key(keydata
, keylen
, output
);