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
41static void
42krb5_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
52static void
53krb5_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
60static void
61krb5_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
73static 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
87static 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
101static krb5_error_code
102CRC32_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
120static krb5_error_code
121RSA_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
133static krb5_error_code
134RSA_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
144static krb5_error_code
145RSA_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
155static krb5_error_code
156RSA_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
166static krb5_error_code
167RSA_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
177struct _krb5_checksum_type _krb5_checksum_crc32 = {
178    CKSUMTYPE_CRC32,
179    "crc32",
180    1,
181    4,
182    0,
183    CRC32_checksum,
184    NULL
185};
186
187struct _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
197struct _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
207struct _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
217static krb5_error_code
218evp_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
237static krb5_error_code
238evp_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
257static krb5_error_code
258DES_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
275static krb5_error_code
276DES_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
292struct _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
308struct _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
324struct _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
340struct _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
356struct _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
372struct _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