Line data Source code
1 : /*
2 : * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
3 : * (Royal Institute of Technology, Stockholm, Sweden).
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions
8 : * are met:
9 : *
10 : * 1. Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : *
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.
16 : *
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.
20 : *
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
31 : * SUCH DAMAGE.
32 : */
33 :
34 : #include "krb5_locl.h"
35 :
36 : /*
37 : *
38 : */
39 :
40 : static void
41 0 : DES3_random_key(krb5_context context,
42 : krb5_keyblock *key)
43 : {
44 0 : DES_cblock *k = key->keyvalue.data;
45 0 : do {
46 0 : krb5_generate_random_block(k, 3 * sizeof(DES_cblock));
47 0 : DES_set_odd_parity(&k[0]);
48 0 : DES_set_odd_parity(&k[1]);
49 0 : DES_set_odd_parity(&k[2]);
50 0 : } while(DES_is_weak_key(&k[0]) ||
51 0 : DES_is_weak_key(&k[1]) ||
52 0 : DES_is_weak_key(&k[2]));
53 0 : }
54 :
55 : static krb5_error_code
56 0 : DES3_prf(krb5_context context,
57 : krb5_crypto crypto,
58 : const krb5_data *in,
59 : krb5_data *out)
60 : {
61 0 : struct _krb5_checksum_type *ct = crypto->et->checksum;
62 0 : struct krb5_crypto_iov iov[1];
63 0 : krb5_error_code ret;
64 0 : Checksum result;
65 0 : krb5_keyblock *derived;
66 :
67 0 : result.cksumtype = ct->type;
68 0 : ret = krb5_data_alloc(&result.checksum, ct->checksumsize);
69 0 : if (ret) {
70 0 : krb5_set_error_message(context, ret, N_("malloc: out memory", ""));
71 0 : return ret;
72 : }
73 :
74 0 : iov[0].data = *in;
75 0 : iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
76 0 : ret = (*ct->checksum)(context, crypto, NULL, 0, iov, 1, &result);
77 0 : if (ret) {
78 0 : krb5_data_free(&result.checksum);
79 0 : return ret;
80 : }
81 :
82 0 : if (result.checksum.length < crypto->et->blocksize)
83 0 : krb5_abortx(context, "internal prf error");
84 :
85 0 : derived = NULL;
86 0 : ret = krb5_derive_key(context, crypto->key.key,
87 0 : crypto->et->type, "prf", 3, &derived);
88 0 : if (ret)
89 0 : krb5_abortx(context, "krb5_derive_key");
90 :
91 0 : ret = krb5_data_alloc(out, crypto->et->prf_length);
92 0 : if (ret)
93 0 : krb5_abortx(context, "malloc failed");
94 :
95 : {
96 0 : const EVP_CIPHER *c = (*crypto->et->keytype->evp)();
97 0 : EVP_CIPHER_CTX ctx;
98 :
99 0 : EVP_CIPHER_CTX_init(&ctx); /* ivec all zero */
100 0 : EVP_CipherInit_ex(&ctx, c, NULL, derived->keyvalue.data, NULL, 1);
101 0 : EVP_Cipher(&ctx, out->data, result.checksum.data,
102 0 : crypto->et->prf_length);
103 0 : EVP_CIPHER_CTX_cleanup(&ctx);
104 : }
105 :
106 0 : krb5_data_free(&result.checksum);
107 0 : krb5_free_keyblock(context, derived);
108 :
109 0 : return ret;
110 : }
111 :
112 : #ifdef DES3_OLD_ENCTYPE
113 : static struct _krb5_key_type keytype_des3 = {
114 : ETYPE_OLD_DES3_CBC_SHA1,
115 : "des3",
116 : 168,
117 : 24,
118 : sizeof(struct _krb5_evp_schedule),
119 : DES3_random_key,
120 : _krb5_evp_schedule,
121 : _krb5_des3_salt,
122 : _krb5_DES3_random_to_key,
123 : _krb5_evp_cleanup,
124 : EVP_des_ede3_cbc
125 : };
126 : #endif
127 :
128 : static struct _krb5_key_type keytype_des3_derived = {
129 : ETYPE_OLD_DES3_CBC_SHA1,
130 : "des3",
131 : 168,
132 : 24,
133 : sizeof(struct _krb5_evp_schedule),
134 : DES3_random_key,
135 : _krb5_evp_schedule,
136 : _krb5_des3_salt_derived,
137 : _krb5_DES3_random_to_key,
138 : _krb5_evp_cleanup,
139 : EVP_des_ede3_cbc
140 : };
141 :
142 : #ifdef DES3_OLD_ENCTYPE
143 : static krb5_error_code
144 0 : RSA_MD5_DES3_checksum(krb5_context context,
145 : krb5_crypto crypto,
146 : struct _krb5_key_data *key,
147 : unsigned usage,
148 : const struct krb5_crypto_iov *iov,
149 : int niov,
150 : Checksum *C)
151 : {
152 0 : return _krb5_des_checksum(context, EVP_md5(), key, iov, niov, C);
153 : }
154 :
155 : static krb5_error_code
156 0 : RSA_MD5_DES3_verify(krb5_context context,
157 : krb5_crypto crypto,
158 : struct _krb5_key_data *key,
159 : unsigned usage,
160 : const struct krb5_crypto_iov *iov,
161 : int niov,
162 : Checksum *C)
163 : {
164 0 : return _krb5_des_verify(context, EVP_md5(), key, iov, niov, C);
165 : }
166 :
167 : struct _krb5_checksum_type _krb5_checksum_rsa_md5_des3 = {
168 : CKSUMTYPE_RSA_MD5_DES3,
169 : "rsa-md5-des3",
170 : 64,
171 : 24,
172 : F_KEYED | F_CPROOF | F_VARIANT,
173 : RSA_MD5_DES3_checksum,
174 : RSA_MD5_DES3_verify
175 : };
176 : #endif
177 :
178 : struct _krb5_checksum_type _krb5_checksum_hmac_sha1_des3 = {
179 : CKSUMTYPE_HMAC_SHA1_DES3,
180 : "hmac-sha1-des3",
181 : 64,
182 : 20,
183 : F_KEYED | F_CPROOF | F_DERIVED,
184 : _krb5_SP_HMAC_SHA1_checksum,
185 : NULL
186 : };
187 :
188 : #ifdef DES3_OLD_ENCTYPE
189 : struct _krb5_encryption_type _krb5_enctype_des3_cbc_md5 = {
190 : ETYPE_DES3_CBC_MD5,
191 : "des3-cbc-md5",
192 : NULL,
193 : 8,
194 : 8,
195 : 8,
196 : &keytype_des3,
197 : &_krb5_checksum_rsa_md5,
198 : &_krb5_checksum_rsa_md5_des3,
199 : F_OLD,
200 : _krb5_evp_encrypt,
201 : _krb5_evp_encrypt_iov,
202 : 0,
203 : NULL
204 : };
205 : #endif
206 :
207 : struct _krb5_encryption_type _krb5_enctype_des3_cbc_sha1 = {
208 : ETYPE_DES3_CBC_SHA1,
209 : "des3-cbc-sha1",
210 : NULL,
211 : 8,
212 : 8,
213 : 8,
214 : &keytype_des3_derived,
215 : &_krb5_checksum_sha1,
216 : &_krb5_checksum_hmac_sha1_des3,
217 : F_DERIVED | F_RFC3961_ENC | F_RFC3961_KDF | F_OLD,
218 : _krb5_evp_encrypt,
219 : _krb5_evp_encrypt_iov,
220 : 16,
221 : DES3_prf
222 : };
223 :
224 : #ifdef DES3_OLD_ENCTYPE
225 : struct _krb5_encryption_type _krb5_enctype_old_des3_cbc_sha1 = {
226 : ETYPE_OLD_DES3_CBC_SHA1,
227 : "old-des3-cbc-sha1",
228 : NULL,
229 : 8,
230 : 8,
231 : 8,
232 : &keytype_des3,
233 : &_krb5_checksum_sha1,
234 : &_krb5_checksum_hmac_sha1_des3,
235 : F_OLD,
236 : _krb5_evp_encrypt,
237 : _krb5_evp_encrypt_iov,
238 : 0,
239 : NULL
240 : };
241 : #endif
242 :
243 : struct _krb5_encryption_type _krb5_enctype_des3_cbc_none = {
244 : ETYPE_DES3_CBC_NONE,
245 : "des3-cbc-none",
246 : NULL,
247 : 8,
248 : 8,
249 : 0,
250 : &keytype_des3_derived,
251 : &_krb5_checksum_none,
252 : NULL,
253 : F_PSEUDO | F_OLD,
254 : _krb5_evp_encrypt,
255 : _krb5_evp_encrypt_iov,
256 : 0,
257 : NULL
258 : };
259 :
260 : void
261 0 : _krb5_DES3_random_to_key(krb5_context context,
262 : krb5_keyblock *key,
263 : const void *data,
264 : size_t size)
265 : {
266 0 : unsigned char *x = key->keyvalue.data;
267 0 : const u_char *q = data;
268 0 : DES_cblock *k;
269 0 : int i, j;
270 :
271 0 : memset(key->keyvalue.data, 0, key->keyvalue.length);
272 0 : for (i = 0; i < 3; ++i) {
273 : unsigned char foo;
274 0 : for (j = 0; j < 7; ++j) {
275 0 : unsigned char b = q[7 * i + j];
276 :
277 0 : x[8 * i + j] = b;
278 : }
279 0 : foo = 0;
280 0 : for (j = 6; j >= 0; --j) {
281 0 : foo |= q[7 * i + j] & 1;
282 0 : foo <<= 1;
283 : }
284 0 : x[8 * i + 7] = foo;
285 : }
286 0 : k = key->keyvalue.data;
287 0 : for (i = 0; i < 3; i++) {
288 0 : DES_set_odd_parity(&k[i]);
289 0 : if(DES_is_weak_key(&k[i]))
290 0 : _krb5_xor8(k[i], (const unsigned char*)"\0\0\0\0\0\0\0\xf0");
291 : }
292 0 : }
|