xref: /netbsd-src/crypto/external/bsd/heimdal/dist/lib/krb5/crypto-des.c (revision afab4e300d3a9fb07dd8c80daf53d0feb3345706)
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