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
39static void
40krb5_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
50static void
51krb5_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
58static void
59krb5_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
71static 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
85static 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
99static krb5_error_code
100CRC32_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
118static krb5_error_code
119RSA_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
131static krb5_error_code
132RSA_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
142static krb5_error_code
143RSA_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
153static krb5_error_code
154RSA_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
164static krb5_error_code
165RSA_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
175struct _krb5_checksum_type _krb5_checksum_crc32 = {
176    CKSUMTYPE_CRC32,
177    "crc32",
178    1,
179    4,
180    0,
181    CRC32_checksum,
182    NULL
183};
184
185struct _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
195struct _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
205struct _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
215static krb5_error_code
216evp_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
234static krb5_error_code
235evp_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
253static krb5_error_code
254DES_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
271static krb5_error_code
272DES_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
288struct _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
303struct _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
318struct _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
333struct _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
348struct _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
363struct _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