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