1 /* $NetBSD: crypto-des.c,v 1.5 2023/06/19 21:41:44 christos Exp $ */
2
3 /*
4 * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 #include "krb5_locl.h"
37
38 #ifdef HEIM_WEAK_CRYPTO
39
40
41 static void
krb5_DES_random_key(krb5_context context,krb5_keyblock * key)42 krb5_DES_random_key(krb5_context context,
43 krb5_keyblock *key)
44 {
45 DES_cblock *k = key->keyvalue.data;
46 do {
47 krb5_generate_random_block(k, sizeof(DES_cblock));
48 DES_set_odd_parity(k);
49 } while(DES_is_weak_key(k));
50 }
51
52 static void
krb5_DES_schedule_old(krb5_context context,struct _krb5_key_type * kt,struct _krb5_key_data * key)53 krb5_DES_schedule_old(krb5_context context,
54 struct _krb5_key_type *kt,
55 struct _krb5_key_data *key)
56 {
57 DES_set_key_unchecked(key->key->keyvalue.data, key->schedule->data);
58 }
59
60 static void
krb5_DES_random_to_key(krb5_context context,krb5_keyblock * key,const void * data,size_t size)61 krb5_DES_random_to_key(krb5_context context,
62 krb5_keyblock *key,
63 const void *data,
64 size_t size)
65 {
66 DES_cblock *k = key->keyvalue.data;
67 memcpy(k, data, key->keyvalue.length);
68 DES_set_odd_parity(k);
69 if(DES_is_weak_key(k))
70 _krb5_xor8(*k, (const unsigned char*)"\0\0\0\0\0\0\0\xf0");
71 }
72
73 static struct _krb5_key_type keytype_des_old = {
74 ETYPE_DES_CBC_CRC,
75 "des-old",
76 56,
77 8,
78 sizeof(DES_key_schedule),
79 krb5_DES_random_key,
80 krb5_DES_schedule_old,
81 _krb5_des_salt,
82 krb5_DES_random_to_key,
83 NULL,
84 NULL
85 };
86
87 static struct _krb5_key_type keytype_des = {
88 ETYPE_DES_CBC_CRC,
89 "des",
90 56,
91 8,
92 sizeof(struct _krb5_evp_schedule),
93 krb5_DES_random_key,
94 _krb5_evp_schedule,
95 _krb5_des_salt,
96 krb5_DES_random_to_key,
97 _krb5_evp_cleanup,
98 EVP_des_cbc
99 };
100
101 static krb5_error_code
CRC32_checksum(krb5_context context,struct _krb5_key_data * key,const void * data,size_t len,unsigned usage,Checksum * C)102 CRC32_checksum(krb5_context context,
103 struct _krb5_key_data *key,
104 const void *data,
105 size_t len,
106 unsigned usage,
107 Checksum *C)
108 {
109 uint32_t crc;
110 unsigned char *r = C->checksum.data;
111 _krb5_crc_init_table ();
112 crc = _krb5_crc_update (data, len, 0);
113 r[0] = crc & 0xff;
114 r[1] = (crc >> 8) & 0xff;
115 r[2] = (crc >> 16) & 0xff;
116 r[3] = (crc >> 24) & 0xff;
117 return 0;
118 }
119
120 static krb5_error_code
RSA_MD4_checksum(krb5_context context,struct _krb5_key_data * key,const void * data,size_t len,unsigned usage,Checksum * C)121 RSA_MD4_checksum(krb5_context context,
122 struct _krb5_key_data *key,
123 const void *data,
124 size_t len,
125 unsigned usage,
126 Checksum *C)
127 {
128 if (EVP_Digest(data, len, C->checksum.data, NULL, EVP_md4(), NULL) != 1)
129 krb5_abortx(context, "md4 checksum failed");
130 return 0;
131 }
132
133 static krb5_error_code
RSA_MD4_DES_checksum(krb5_context context,struct _krb5_key_data * key,const void * data,size_t len,unsigned usage,Checksum * cksum)134 RSA_MD4_DES_checksum(krb5_context context,
135 struct _krb5_key_data *key,
136 const void *data,
137 size_t len,
138 unsigned usage,
139 Checksum *cksum)
140 {
141 return _krb5_des_checksum(context, EVP_md4(), key, data, len, cksum);
142 }
143
144 static krb5_error_code
RSA_MD4_DES_verify(krb5_context context,struct _krb5_key_data * key,const void * data,size_t len,unsigned usage,Checksum * C)145 RSA_MD4_DES_verify(krb5_context context,
146 struct _krb5_key_data *key,
147 const void *data,
148 size_t len,
149 unsigned usage,
150 Checksum *C)
151 {
152 return _krb5_des_verify(context, EVP_md4(), key, data, len, C);
153 }
154
155 static krb5_error_code
RSA_MD5_DES_checksum(krb5_context context,struct _krb5_key_data * key,const void * data,size_t len,unsigned usage,Checksum * C)156 RSA_MD5_DES_checksum(krb5_context context,
157 struct _krb5_key_data *key,
158 const void *data,
159 size_t len,
160 unsigned usage,
161 Checksum *C)
162 {
163 return _krb5_des_checksum(context, EVP_md5(), key, data, len, C);
164 }
165
166 static krb5_error_code
RSA_MD5_DES_verify(krb5_context context,struct _krb5_key_data * key,const void * data,size_t len,unsigned usage,Checksum * C)167 RSA_MD5_DES_verify(krb5_context context,
168 struct _krb5_key_data *key,
169 const void *data,
170 size_t len,
171 unsigned usage,
172 Checksum *C)
173 {
174 return _krb5_des_verify(context, EVP_md5(), key, data, len, C);
175 }
176
177 struct _krb5_checksum_type _krb5_checksum_crc32 = {
178 CKSUMTYPE_CRC32,
179 "crc32",
180 1,
181 4,
182 0,
183 CRC32_checksum,
184 NULL
185 };
186
187 struct _krb5_checksum_type _krb5_checksum_rsa_md4 = {
188 CKSUMTYPE_RSA_MD4,
189 "rsa-md4",
190 64,
191 16,
192 F_CPROOF,
193 RSA_MD4_checksum,
194 NULL
195 };
196
197 struct _krb5_checksum_type _krb5_checksum_rsa_md4_des = {
198 CKSUMTYPE_RSA_MD4_DES,
199 "rsa-md4-des",
200 64,
201 24,
202 F_KEYED | F_CPROOF | F_VARIANT,
203 RSA_MD4_DES_checksum,
204 RSA_MD4_DES_verify
205 };
206
207 struct _krb5_checksum_type _krb5_checksum_rsa_md5_des = {
208 CKSUMTYPE_RSA_MD5_DES,
209 "rsa-md5-des",
210 64,
211 24,
212 F_KEYED | F_CPROOF | F_VARIANT,
213 RSA_MD5_DES_checksum,
214 RSA_MD5_DES_verify
215 };
216
217 static krb5_error_code
evp_des_encrypt_null_ivec(krb5_context context,struct _krb5_key_data * key,void * data,size_t len,krb5_boolean encryptp,int usage,void * ignore_ivec)218 evp_des_encrypt_null_ivec(krb5_context context,
219 struct _krb5_key_data *key,
220 void *data,
221 size_t len,
222 krb5_boolean encryptp,
223 int usage,
224 void *ignore_ivec)
225 {
226 struct _krb5_evp_schedule *ctx = key->schedule->data;
227 EVP_CIPHER_CTX *c;
228 DES_cblock ivec;
229 memset(&ivec, 0, sizeof(ivec));
230 c = encryptp ? ctx->ectx : ctx->dctx;
231 if (!EVP_CipherInit_ex(c, NULL, NULL, NULL, (void *)&ivec, -1))
232 krb5_abortx(context, "can't initialize cipher");
233 EVP_Cipher(c, data, data, len);
234 return 0;
235 }
236
237 static krb5_error_code
evp_des_encrypt_key_ivec(krb5_context context,struct _krb5_key_data * key,void * data,size_t len,krb5_boolean encryptp,int usage,void * ignore_ivec)238 evp_des_encrypt_key_ivec(krb5_context context,
239 struct _krb5_key_data *key,
240 void *data,
241 size_t len,
242 krb5_boolean encryptp,
243 int usage,
244 void *ignore_ivec)
245 {
246 struct _krb5_evp_schedule *ctx = key->schedule->data;
247 EVP_CIPHER_CTX *c;
248 DES_cblock ivec;
249 memcpy(&ivec, key->key->keyvalue.data, sizeof(ivec));
250 c = encryptp ? ctx->ectx : ctx->dctx;
251 if (!EVP_CipherInit_ex(c, NULL, NULL, NULL, (void *)&ivec, -1))
252 krb5_abortx(context, "can't initialize cipher");
253 EVP_Cipher(c, data, data, len);
254 return 0;
255 }
256
257 static krb5_error_code
DES_CFB64_encrypt_null_ivec(krb5_context context,struct _krb5_key_data * key,void * data,size_t len,krb5_boolean encryptp,int usage,void * ignore_ivec)258 DES_CFB64_encrypt_null_ivec(krb5_context context,
259 struct _krb5_key_data *key,
260 void *data,
261 size_t len,
262 krb5_boolean encryptp,
263 int usage,
264 void *ignore_ivec)
265 {
266 DES_cblock ivec;
267 int num = 0;
268 DES_key_schedule *s = key->schedule->data;
269 memset(&ivec, 0, sizeof(ivec));
270
271 DES_cfb64_encrypt(data, data, len, s, &ivec, &num, encryptp);
272 return 0;
273 }
274
275 static krb5_error_code
DES_PCBC_encrypt_key_ivec(krb5_context context,struct _krb5_key_data * key,void * data,size_t len,krb5_boolean encryptp,int usage,void * ignore_ivec)276 DES_PCBC_encrypt_key_ivec(krb5_context context,
277 struct _krb5_key_data *key,
278 void *data,
279 size_t len,
280 krb5_boolean encryptp,
281 int usage,
282 void *ignore_ivec)
283 {
284 DES_cblock ivec;
285 DES_key_schedule *s = key->schedule->data;
286 memcpy(&ivec, key->key->keyvalue.data, sizeof(ivec));
287
288 DES_pcbc_encrypt(data, data, len, s, &ivec, encryptp);
289 return 0;
290 }
291
292 struct _krb5_encryption_type _krb5_enctype_des_cbc_crc = {
293 ETYPE_DES_CBC_CRC,
294 "des-cbc-crc",
295 NULL,
296 8,
297 8,
298 8,
299 &keytype_des,
300 &_krb5_checksum_crc32,
301 NULL,
302 F_DISABLED|F_WEAK,
303 evp_des_encrypt_key_ivec,
304 0,
305 NULL
306 };
307
308 struct _krb5_encryption_type _krb5_enctype_des_cbc_md4 = {
309 ETYPE_DES_CBC_MD4,
310 "des-cbc-md4",
311 NULL,
312 8,
313 8,
314 8,
315 &keytype_des,
316 &_krb5_checksum_rsa_md4,
317 &_krb5_checksum_rsa_md4_des,
318 F_DISABLED|F_WEAK,
319 evp_des_encrypt_null_ivec,
320 0,
321 NULL
322 };
323
324 struct _krb5_encryption_type _krb5_enctype_des_cbc_md5 = {
325 ETYPE_DES_CBC_MD5,
326 "des-cbc-md5",
327 NULL,
328 8,
329 8,
330 8,
331 &keytype_des,
332 &_krb5_checksum_rsa_md5,
333 &_krb5_checksum_rsa_md5_des,
334 F_DISABLED|F_WEAK,
335 evp_des_encrypt_null_ivec,
336 0,
337 NULL
338 };
339
340 struct _krb5_encryption_type _krb5_enctype_des_cbc_none = {
341 ETYPE_DES_CBC_NONE,
342 "des-cbc-none",
343 NULL,
344 8,
345 8,
346 0,
347 &keytype_des,
348 &_krb5_checksum_none,
349 NULL,
350 F_PSEUDO|F_DISABLED|F_WEAK,
351 evp_des_encrypt_null_ivec,
352 0,
353 NULL
354 };
355
356 struct _krb5_encryption_type _krb5_enctype_des_cfb64_none = {
357 ETYPE_DES_CFB64_NONE,
358 "des-cfb64-none",
359 NULL,
360 1,
361 1,
362 0,
363 &keytype_des_old,
364 &_krb5_checksum_none,
365 NULL,
366 F_PSEUDO|F_DISABLED|F_WEAK,
367 DES_CFB64_encrypt_null_ivec,
368 0,
369 NULL
370 };
371
372 struct _krb5_encryption_type _krb5_enctype_des_pcbc_none = {
373 ETYPE_DES_PCBC_NONE,
374 "des-pcbc-none",
375 NULL,
376 8,
377 8,
378 0,
379 &keytype_des_old,
380 &_krb5_checksum_none,
381 NULL,
382 F_PSEUDO|F_DISABLED|F_WEAK,
383 DES_PCBC_encrypt_key_ivec,
384 0,
385 NULL
386 };
387 #endif /* HEIM_WEAK_CRYPTO */
388