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