xref: /freebsd/crypto/heimdal/lib/krb5/crypto-des.c (revision 8ddb146abcdf061be9f2c0db7e391697dafad85c)
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 #ifdef HEIM_WEAK_CRYPTO
37 
38 
39 static void
40 krb5_DES_random_key(krb5_context context,
41 		    krb5_keyblock *key)
42 {
43     DES_cblock *k = key->keyvalue.data;
44     do {
45 	krb5_generate_random_block(k, sizeof(DES_cblock));
46 	DES_set_odd_parity(k);
47     } while(DES_is_weak_key(k));
48 }
49 
50 static void
51 krb5_DES_schedule_old(krb5_context context,
52 		      struct _krb5_key_type *kt,
53 		      struct _krb5_key_data *key)
54 {
55     DES_set_key_unchecked(key->key->keyvalue.data, key->schedule->data);
56 }
57 
58 static void
59 krb5_DES_random_to_key(krb5_context context,
60 		       krb5_keyblock *key,
61 		       const void *data,
62 		       size_t size)
63 {
64     DES_cblock *k = key->keyvalue.data;
65     memcpy(k, data, key->keyvalue.length);
66     DES_set_odd_parity(k);
67     if(DES_is_weak_key(k))
68 	_krb5_xor(k, (const unsigned char*)"\0\0\0\0\0\0\0\xf0");
69 }
70 
71 static struct _krb5_key_type keytype_des_old = {
72     ETYPE_DES_CBC_CRC,
73     "des-old",
74     56,
75     8,
76     sizeof(DES_key_schedule),
77     krb5_DES_random_key,
78     krb5_DES_schedule_old,
79     _krb5_des_salt,
80     krb5_DES_random_to_key,
81     NULL,
82     NULL
83 };
84 
85 static struct _krb5_key_type keytype_des = {
86     ETYPE_DES_CBC_CRC,
87     "des",
88     56,
89     8,
90     sizeof(struct _krb5_evp_schedule),
91     krb5_DES_random_key,
92     _krb5_evp_schedule,
93     _krb5_des_salt,
94     krb5_DES_random_to_key,
95     _krb5_evp_cleanup,
96     EVP_des_cbc
97 };
98 
99 static krb5_error_code
100 CRC32_checksum(krb5_context context,
101 	       struct _krb5_key_data *key,
102 	       const void *data,
103 	       size_t len,
104 	       unsigned usage,
105 	       Checksum *C)
106 {
107     uint32_t crc;
108     unsigned char *r = C->checksum.data;
109     _krb5_crc_init_table ();
110     crc = _krb5_crc_update (data, len, 0);
111     r[0] = crc & 0xff;
112     r[1] = (crc >> 8)  & 0xff;
113     r[2] = (crc >> 16) & 0xff;
114     r[3] = (crc >> 24) & 0xff;
115     return 0;
116 }
117 
118 static krb5_error_code
119 RSA_MD4_checksum(krb5_context context,
120 		 struct _krb5_key_data *key,
121 		 const void *data,
122 		 size_t len,
123 		 unsigned usage,
124 		 Checksum *C)
125 {
126     if (EVP_Digest(data, len, C->checksum.data, NULL, EVP_md4(), NULL) != 1)
127 	krb5_abortx(context, "md4 checksum failed");
128     return 0;
129 }
130 
131 static krb5_error_code
132 RSA_MD4_DES_checksum(krb5_context context,
133 		     struct _krb5_key_data *key,
134 		     const void *data,
135 		     size_t len,
136 		     unsigned usage,
137 		     Checksum *cksum)
138 {
139     return _krb5_des_checksum(context, EVP_md4(), key, data, len, cksum);
140 }
141 
142 static krb5_error_code
143 RSA_MD4_DES_verify(krb5_context context,
144 		   struct _krb5_key_data *key,
145 		   const void *data,
146 		   size_t len,
147 		   unsigned usage,
148 		   Checksum *C)
149 {
150     return _krb5_des_verify(context, EVP_md4(), key, data, len, C);
151 }
152 
153 static krb5_error_code
154 RSA_MD5_DES_checksum(krb5_context context,
155 		     struct _krb5_key_data *key,
156 		     const void *data,
157 		     size_t len,
158 		     unsigned usage,
159 		     Checksum *C)
160 {
161     return _krb5_des_checksum(context, EVP_md5(), key, data, len, C);
162 }
163 
164 static krb5_error_code
165 RSA_MD5_DES_verify(krb5_context context,
166 		   struct _krb5_key_data *key,
167 		   const void *data,
168 		   size_t len,
169 		   unsigned usage,
170 		   Checksum *C)
171 {
172     return _krb5_des_verify(context, EVP_md5(), key, data, len, C);
173 }
174 
175 struct _krb5_checksum_type _krb5_checksum_crc32 = {
176     CKSUMTYPE_CRC32,
177     "crc32",
178     1,
179     4,
180     0,
181     CRC32_checksum,
182     NULL
183 };
184 
185 struct _krb5_checksum_type _krb5_checksum_rsa_md4 = {
186     CKSUMTYPE_RSA_MD4,
187     "rsa-md4",
188     64,
189     16,
190     F_CPROOF,
191     RSA_MD4_checksum,
192     NULL
193 };
194 
195 struct _krb5_checksum_type _krb5_checksum_rsa_md4_des = {
196     CKSUMTYPE_RSA_MD4_DES,
197     "rsa-md4-des",
198     64,
199     24,
200     F_KEYED | F_CPROOF | F_VARIANT,
201     RSA_MD4_DES_checksum,
202     RSA_MD4_DES_verify
203 };
204 
205 struct _krb5_checksum_type _krb5_checksum_rsa_md5_des = {
206     CKSUMTYPE_RSA_MD5_DES,
207     "rsa-md5-des",
208     64,
209     24,
210     F_KEYED | F_CPROOF | F_VARIANT,
211     RSA_MD5_DES_checksum,
212     RSA_MD5_DES_verify
213 };
214 
215 static krb5_error_code
216 evp_des_encrypt_null_ivec(krb5_context context,
217 			  struct _krb5_key_data *key,
218 			  void *data,
219 			  size_t len,
220 			  krb5_boolean encryptp,
221 			  int usage,
222 			  void *ignore_ivec)
223 {
224     struct _krb5_evp_schedule *ctx = key->schedule->data;
225     EVP_CIPHER_CTX *c;
226     DES_cblock ivec;
227     memset(&ivec, 0, sizeof(ivec));
228     c = encryptp ? ctx->ectx : ctx->dctx;
229     EVP_CipherInit_ex(c, NULL, NULL, NULL, (void *)&ivec, -1);
230     EVP_Cipher(c, data, data, len);
231     return 0;
232 }
233 
234 static krb5_error_code
235 evp_des_encrypt_key_ivec(krb5_context context,
236 			 struct _krb5_key_data *key,
237 			 void *data,
238 			 size_t len,
239 			 krb5_boolean encryptp,
240 			 int usage,
241 			 void *ignore_ivec)
242 {
243     struct _krb5_evp_schedule *ctx = key->schedule->data;
244     EVP_CIPHER_CTX *c;
245     DES_cblock ivec;
246     memcpy(&ivec, key->key->keyvalue.data, sizeof(ivec));
247     c = encryptp ? ctx->ectx : ctx->dctx;
248     EVP_CipherInit_ex(c, NULL, NULL, NULL, (void *)&ivec, -1);
249     EVP_Cipher(c, data, data, len);
250     return 0;
251 }
252 
253 static krb5_error_code
254 DES_CFB64_encrypt_null_ivec(krb5_context context,
255 			    struct _krb5_key_data *key,
256 			    void *data,
257 			    size_t len,
258 			    krb5_boolean encryptp,
259 			    int usage,
260 			    void *ignore_ivec)
261 {
262     DES_cblock ivec;
263     int num = 0;
264     DES_key_schedule *s = key->schedule->data;
265     memset(&ivec, 0, sizeof(ivec));
266 
267     DES_cfb64_encrypt(data, data, len, s, &ivec, &num, encryptp);
268     return 0;
269 }
270 
271 static krb5_error_code
272 DES_PCBC_encrypt_key_ivec(krb5_context context,
273 			  struct _krb5_key_data *key,
274 			  void *data,
275 			  size_t len,
276 			  krb5_boolean encryptp,
277 			  int usage,
278 			  void *ignore_ivec)
279 {
280     DES_cblock ivec;
281     DES_key_schedule *s = key->schedule->data;
282     memcpy(&ivec, key->key->keyvalue.data, sizeof(ivec));
283 
284     DES_pcbc_encrypt(data, data, len, s, &ivec, encryptp);
285     return 0;
286 }
287 
288 struct _krb5_encryption_type _krb5_enctype_des_cbc_crc = {
289     ETYPE_DES_CBC_CRC,
290     "des-cbc-crc",
291     8,
292     8,
293     8,
294     &keytype_des,
295     &_krb5_checksum_crc32,
296     NULL,
297     F_DISABLED|F_WEAK,
298     evp_des_encrypt_key_ivec,
299     0,
300     NULL
301 };
302 
303 struct _krb5_encryption_type _krb5_enctype_des_cbc_md4 = {
304     ETYPE_DES_CBC_MD4,
305     "des-cbc-md4",
306     8,
307     8,
308     8,
309     &keytype_des,
310     &_krb5_checksum_rsa_md4,
311     &_krb5_checksum_rsa_md4_des,
312     F_DISABLED|F_WEAK,
313     evp_des_encrypt_null_ivec,
314     0,
315     NULL
316 };
317 
318 struct _krb5_encryption_type _krb5_enctype_des_cbc_md5 = {
319     ETYPE_DES_CBC_MD5,
320     "des-cbc-md5",
321     8,
322     8,
323     8,
324     &keytype_des,
325     &_krb5_checksum_rsa_md5,
326     &_krb5_checksum_rsa_md5_des,
327     F_DISABLED|F_WEAK,
328     evp_des_encrypt_null_ivec,
329     0,
330     NULL
331 };
332 
333 struct _krb5_encryption_type _krb5_enctype_des_cbc_none = {
334     ETYPE_DES_CBC_NONE,
335     "des-cbc-none",
336     8,
337     8,
338     0,
339     &keytype_des,
340     &_krb5_checksum_none,
341     NULL,
342     F_PSEUDO|F_DISABLED|F_WEAK,
343     evp_des_encrypt_null_ivec,
344     0,
345     NULL
346 };
347 
348 struct _krb5_encryption_type _krb5_enctype_des_cfb64_none = {
349     ETYPE_DES_CFB64_NONE,
350     "des-cfb64-none",
351     1,
352     1,
353     0,
354     &keytype_des_old,
355     &_krb5_checksum_none,
356     NULL,
357     F_PSEUDO|F_DISABLED|F_WEAK,
358     DES_CFB64_encrypt_null_ivec,
359     0,
360     NULL
361 };
362 
363 struct _krb5_encryption_type _krb5_enctype_des_pcbc_none = {
364     ETYPE_DES_PCBC_NONE,
365     "des-pcbc-none",
366     8,
367     8,
368     0,
369     &keytype_des_old,
370     &_krb5_checksum_none,
371     NULL,
372     F_PSEUDO|F_DISABLED|F_WEAK,
373     DES_PCBC_encrypt_key_ivec,
374     0,
375     NULL
376 };
377 #endif /* HEIM_WEAK_CRYPTO */
378