1226031Sstas/*
2226031Sstas * Copyright (c) 1997 - 2008 Kungliga Tekniska H��gskolan
3226031Sstas * (Royal Institute of Technology, Stockholm, Sweden).
4226031Sstas * All rights reserved.
5226031Sstas *
6226031Sstas * Redistribution and use in source and binary forms, with or without
7226031Sstas * modification, are permitted provided that the following conditions
8226031Sstas * are met:
9226031Sstas *
10226031Sstas * 1. Redistributions of source code must retain the above copyright
11226031Sstas *    notice, this list of conditions and the following disclaimer.
12226031Sstas *
13226031Sstas * 2. Redistributions in binary form must reproduce the above copyright
14226031Sstas *    notice, this list of conditions and the following disclaimer in the
15226031Sstas *    documentation and/or other materials provided with the distribution.
16226031Sstas *
17226031Sstas * 3. Neither the name of the Institute nor the names of its contributors
18226031Sstas *    may be used to endorse or promote products derived from this software
19226031Sstas *    without specific prior written permission.
20226031Sstas *
21226031Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22226031Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23226031Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24226031Sstas * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25226031Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26226031Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27226031Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28226031Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29226031Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30226031Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31226031Sstas * SUCH DAMAGE.
32226031Sstas */
33226031Sstas
34226031Sstas#include "krb5_locl.h"
35226031Sstas
36226031Sstas#ifdef HEIM_WEAK_CRYPTO
37226031Sstas
38226031Sstas
39226031Sstasstatic void
40226031Sstaskrb5_DES_random_key(krb5_context context,
41226031Sstas		    krb5_keyblock *key)
42226031Sstas{
43226031Sstas    DES_cblock *k = key->keyvalue.data;
44226031Sstas    do {
45226031Sstas	krb5_generate_random_block(k, sizeof(DES_cblock));
46226031Sstas	DES_set_odd_parity(k);
47226031Sstas    } while(DES_is_weak_key(k));
48226031Sstas}
49226031Sstas
50226031Sstasstatic void
51226031Sstaskrb5_DES_schedule_old(krb5_context context,
52226031Sstas		      struct _krb5_key_type *kt,
53226031Sstas		      struct _krb5_key_data *key)
54226031Sstas{
55226031Sstas    DES_set_key_unchecked(key->key->keyvalue.data, key->schedule->data);
56226031Sstas}
57226031Sstas
58226031Sstasstatic void
59226031Sstaskrb5_DES_random_to_key(krb5_context context,
60226031Sstas		       krb5_keyblock *key,
61226031Sstas		       const void *data,
62226031Sstas		       size_t size)
63226031Sstas{
64226031Sstas    DES_cblock *k = key->keyvalue.data;
65226031Sstas    memcpy(k, data, key->keyvalue.length);
66226031Sstas    DES_set_odd_parity(k);
67226031Sstas    if(DES_is_weak_key(k))
68226031Sstas	_krb5_xor(k, (const unsigned char*)"\0\0\0\0\0\0\0\xf0");
69226031Sstas}
70226031Sstas
71226031Sstasstatic struct _krb5_key_type keytype_des_old = {
72226031Sstas    ETYPE_DES_CBC_CRC,
73226031Sstas    "des-old",
74226031Sstas    56,
75226031Sstas    8,
76226031Sstas    sizeof(DES_key_schedule),
77226031Sstas    krb5_DES_random_key,
78226031Sstas    krb5_DES_schedule_old,
79226031Sstas    _krb5_des_salt,
80226031Sstas    krb5_DES_random_to_key,
81226031Sstas    NULL,
82226031Sstas    NULL
83226031Sstas};
84226031Sstas
85226031Sstasstatic struct _krb5_key_type keytype_des = {
86226031Sstas    ETYPE_DES_CBC_CRC,
87226031Sstas    "des",
88226031Sstas    56,
89226031Sstas    8,
90226031Sstas    sizeof(struct _krb5_evp_schedule),
91226031Sstas    krb5_DES_random_key,
92226031Sstas    _krb5_evp_schedule,
93226031Sstas    _krb5_des_salt,
94226031Sstas    krb5_DES_random_to_key,
95226031Sstas    _krb5_evp_cleanup,
96226031Sstas    EVP_des_cbc
97226031Sstas};
98226031Sstas
99226031Sstasstatic krb5_error_code
100226031SstasCRC32_checksum(krb5_context context,
101226031Sstas	       struct _krb5_key_data *key,
102226031Sstas	       const void *data,
103226031Sstas	       size_t len,
104226031Sstas	       unsigned usage,
105226031Sstas	       Checksum *C)
106226031Sstas{
107226031Sstas    uint32_t crc;
108226031Sstas    unsigned char *r = C->checksum.data;
109226031Sstas    _krb5_crc_init_table ();
110226031Sstas    crc = _krb5_crc_update (data, len, 0);
111226031Sstas    r[0] = crc & 0xff;
112226031Sstas    r[1] = (crc >> 8)  & 0xff;
113226031Sstas    r[2] = (crc >> 16) & 0xff;
114226031Sstas    r[3] = (crc >> 24) & 0xff;
115226031Sstas    return 0;
116226031Sstas}
117226031Sstas
118226031Sstasstatic krb5_error_code
119226031SstasRSA_MD4_checksum(krb5_context context,
120226031Sstas		 struct _krb5_key_data *key,
121226031Sstas		 const void *data,
122226031Sstas		 size_t len,
123226031Sstas		 unsigned usage,
124226031Sstas		 Checksum *C)
125226031Sstas{
126226031Sstas    if (EVP_Digest(data, len, C->checksum.data, NULL, EVP_md4(), NULL) != 1)
127226031Sstas	krb5_abortx(context, "md4 checksum failed");
128226031Sstas    return 0;
129226031Sstas}
130226031Sstas
131226031Sstasstatic krb5_error_code
132226031SstasRSA_MD4_DES_checksum(krb5_context context,
133226031Sstas		     struct _krb5_key_data *key,
134226031Sstas		     const void *data,
135226031Sstas		     size_t len,
136226031Sstas		     unsigned usage,
137226031Sstas		     Checksum *cksum)
138226031Sstas{
139226031Sstas    return _krb5_des_checksum(context, EVP_md4(), key, data, len, cksum);
140226031Sstas}
141226031Sstas
142226031Sstasstatic krb5_error_code
143226031SstasRSA_MD4_DES_verify(krb5_context context,
144226031Sstas		   struct _krb5_key_data *key,
145226031Sstas		   const void *data,
146226031Sstas		   size_t len,
147226031Sstas		   unsigned usage,
148226031Sstas		   Checksum *C)
149226031Sstas{
150226031Sstas    return _krb5_des_verify(context, EVP_md4(), key, data, len, C);
151226031Sstas}
152226031Sstas
153226031Sstasstatic krb5_error_code
154226031SstasRSA_MD5_DES_checksum(krb5_context context,
155226031Sstas		     struct _krb5_key_data *key,
156226031Sstas		     const void *data,
157226031Sstas		     size_t len,
158226031Sstas		     unsigned usage,
159226031Sstas		     Checksum *C)
160226031Sstas{
161226031Sstas    return _krb5_des_checksum(context, EVP_md5(), key, data, len, C);
162226031Sstas}
163226031Sstas
164226031Sstasstatic krb5_error_code
165226031SstasRSA_MD5_DES_verify(krb5_context context,
166226031Sstas		   struct _krb5_key_data *key,
167226031Sstas		   const void *data,
168226031Sstas		   size_t len,
169226031Sstas		   unsigned usage,
170226031Sstas		   Checksum *C)
171226031Sstas{
172226031Sstas    return _krb5_des_verify(context, EVP_md5(), key, data, len, C);
173226031Sstas}
174226031Sstas
175226031Sstasstruct _krb5_checksum_type _krb5_checksum_crc32 = {
176226031Sstas    CKSUMTYPE_CRC32,
177226031Sstas    "crc32",
178226031Sstas    1,
179226031Sstas    4,
180226031Sstas    0,
181226031Sstas    CRC32_checksum,
182226031Sstas    NULL
183226031Sstas};
184226031Sstas
185226031Sstasstruct _krb5_checksum_type _krb5_checksum_rsa_md4 = {
186226031Sstas    CKSUMTYPE_RSA_MD4,
187226031Sstas    "rsa-md4",
188226031Sstas    64,
189226031Sstas    16,
190226031Sstas    F_CPROOF,
191226031Sstas    RSA_MD4_checksum,
192226031Sstas    NULL
193226031Sstas};
194226031Sstas
195226031Sstasstruct _krb5_checksum_type _krb5_checksum_rsa_md4_des = {
196226031Sstas    CKSUMTYPE_RSA_MD4_DES,
197226031Sstas    "rsa-md4-des",
198226031Sstas    64,
199226031Sstas    24,
200226031Sstas    F_KEYED | F_CPROOF | F_VARIANT,
201226031Sstas    RSA_MD4_DES_checksum,
202226031Sstas    RSA_MD4_DES_verify
203226031Sstas};
204226031Sstas
205226031Sstasstruct _krb5_checksum_type _krb5_checksum_rsa_md5_des = {
206226031Sstas    CKSUMTYPE_RSA_MD5_DES,
207226031Sstas    "rsa-md5-des",
208226031Sstas    64,
209226031Sstas    24,
210226031Sstas    F_KEYED | F_CPROOF | F_VARIANT,
211226031Sstas    RSA_MD5_DES_checksum,
212226031Sstas    RSA_MD5_DES_verify
213226031Sstas};
214226031Sstas
215226031Sstasstatic krb5_error_code
216226031Sstasevp_des_encrypt_null_ivec(krb5_context context,
217226031Sstas			  struct _krb5_key_data *key,
218226031Sstas			  void *data,
219226031Sstas			  size_t len,
220226031Sstas			  krb5_boolean encryptp,
221226031Sstas			  int usage,
222226031Sstas			  void *ignore_ivec)
223226031Sstas{
224226031Sstas    struct _krb5_evp_schedule *ctx = key->schedule->data;
225226031Sstas    EVP_CIPHER_CTX *c;
226226031Sstas    DES_cblock ivec;
227226031Sstas    memset(&ivec, 0, sizeof(ivec));
228226031Sstas    c = encryptp ? &ctx->ectx : &ctx->dctx;
229226031Sstas    EVP_CipherInit_ex(c, NULL, NULL, NULL, (void *)&ivec, -1);
230226031Sstas    EVP_Cipher(c, data, data, len);
231226031Sstas    return 0;
232226031Sstas}
233226031Sstas
234226031Sstasstatic krb5_error_code
235226031Sstasevp_des_encrypt_key_ivec(krb5_context context,
236226031Sstas			 struct _krb5_key_data *key,
237226031Sstas			 void *data,
238226031Sstas			 size_t len,
239226031Sstas			 krb5_boolean encryptp,
240226031Sstas			 int usage,
241226031Sstas			 void *ignore_ivec)
242226031Sstas{
243226031Sstas    struct _krb5_evp_schedule *ctx = key->schedule->data;
244226031Sstas    EVP_CIPHER_CTX *c;
245226031Sstas    DES_cblock ivec;
246226031Sstas    memcpy(&ivec, key->key->keyvalue.data, sizeof(ivec));
247226031Sstas    c = encryptp ? &ctx->ectx : &ctx->dctx;
248226031Sstas    EVP_CipherInit_ex(c, NULL, NULL, NULL, (void *)&ivec, -1);
249226031Sstas    EVP_Cipher(c, data, data, len);
250226031Sstas    return 0;
251226031Sstas}
252226031Sstas
253226031Sstasstatic krb5_error_code
254226031SstasDES_CFB64_encrypt_null_ivec(krb5_context context,
255226031Sstas			    struct _krb5_key_data *key,
256226031Sstas			    void *data,
257226031Sstas			    size_t len,
258226031Sstas			    krb5_boolean encryptp,
259226031Sstas			    int usage,
260226031Sstas			    void *ignore_ivec)
261226031Sstas{
262226031Sstas    DES_cblock ivec;
263226031Sstas    int num = 0;
264226031Sstas    DES_key_schedule *s = key->schedule->data;
265226031Sstas    memset(&ivec, 0, sizeof(ivec));
266226031Sstas
267226031Sstas    DES_cfb64_encrypt(data, data, len, s, &ivec, &num, encryptp);
268226031Sstas    return 0;
269226031Sstas}
270226031Sstas
271226031Sstasstatic krb5_error_code
272226031SstasDES_PCBC_encrypt_key_ivec(krb5_context context,
273226031Sstas			  struct _krb5_key_data *key,
274226031Sstas			  void *data,
275226031Sstas			  size_t len,
276226031Sstas			  krb5_boolean encryptp,
277226031Sstas			  int usage,
278226031Sstas			  void *ignore_ivec)
279226031Sstas{
280226031Sstas    DES_cblock ivec;
281226031Sstas    DES_key_schedule *s = key->schedule->data;
282226031Sstas    memcpy(&ivec, key->key->keyvalue.data, sizeof(ivec));
283226031Sstas
284226031Sstas    DES_pcbc_encrypt(data, data, len, s, &ivec, encryptp);
285226031Sstas    return 0;
286226031Sstas}
287226031Sstas
288226031Sstasstruct _krb5_encryption_type _krb5_enctype_des_cbc_crc = {
289226031Sstas    ETYPE_DES_CBC_CRC,
290226031Sstas    "des-cbc-crc",
291226031Sstas    8,
292226031Sstas    8,
293226031Sstas    8,
294226031Sstas    &keytype_des,
295226031Sstas    &_krb5_checksum_crc32,
296226031Sstas    NULL,
297226031Sstas    F_DISABLED|F_WEAK,
298226031Sstas    evp_des_encrypt_key_ivec,
299226031Sstas    0,
300226031Sstas    NULL
301226031Sstas};
302226031Sstas
303226031Sstasstruct _krb5_encryption_type _krb5_enctype_des_cbc_md4 = {
304226031Sstas    ETYPE_DES_CBC_MD4,
305226031Sstas    "des-cbc-md4",
306226031Sstas    8,
307226031Sstas    8,
308226031Sstas    8,
309226031Sstas    &keytype_des,
310226031Sstas    &_krb5_checksum_rsa_md4,
311226031Sstas    &_krb5_checksum_rsa_md4_des,
312226031Sstas    F_DISABLED|F_WEAK,
313226031Sstas    evp_des_encrypt_null_ivec,
314226031Sstas    0,
315226031Sstas    NULL
316226031Sstas};
317226031Sstas
318226031Sstasstruct _krb5_encryption_type _krb5_enctype_des_cbc_md5 = {
319226031Sstas    ETYPE_DES_CBC_MD5,
320226031Sstas    "des-cbc-md5",
321226031Sstas    8,
322226031Sstas    8,
323226031Sstas    8,
324226031Sstas    &keytype_des,
325226031Sstas    &_krb5_checksum_rsa_md5,
326226031Sstas    &_krb5_checksum_rsa_md5_des,
327226031Sstas    F_DISABLED|F_WEAK,
328226031Sstas    evp_des_encrypt_null_ivec,
329226031Sstas    0,
330226031Sstas    NULL
331226031Sstas};
332226031Sstas
333226031Sstasstruct _krb5_encryption_type _krb5_enctype_des_cbc_none = {
334226031Sstas    ETYPE_DES_CBC_NONE,
335226031Sstas    "des-cbc-none",
336226031Sstas    8,
337226031Sstas    8,
338226031Sstas    0,
339226031Sstas    &keytype_des,
340226031Sstas    &_krb5_checksum_none,
341226031Sstas    NULL,
342226031Sstas    F_PSEUDO|F_DISABLED|F_WEAK,
343226031Sstas    evp_des_encrypt_null_ivec,
344226031Sstas    0,
345226031Sstas    NULL
346226031Sstas};
347226031Sstas
348226031Sstasstruct _krb5_encryption_type _krb5_enctype_des_cfb64_none = {
349226031Sstas    ETYPE_DES_CFB64_NONE,
350226031Sstas    "des-cfb64-none",
351226031Sstas    1,
352226031Sstas    1,
353226031Sstas    0,
354226031Sstas    &keytype_des_old,
355226031Sstas    &_krb5_checksum_none,
356226031Sstas    NULL,
357226031Sstas    F_PSEUDO|F_DISABLED|F_WEAK,
358226031Sstas    DES_CFB64_encrypt_null_ivec,
359226031Sstas    0,
360226031Sstas    NULL
361226031Sstas};
362226031Sstas
363226031Sstasstruct _krb5_encryption_type _krb5_enctype_des_pcbc_none = {
364226031Sstas    ETYPE_DES_PCBC_NONE,
365226031Sstas    "des-pcbc-none",
366226031Sstas    8,
367226031Sstas    8,
368226031Sstas    0,
369226031Sstas    &keytype_des_old,
370226031Sstas    &_krb5_checksum_none,
371226031Sstas    NULL,
372226031Sstas    F_PSEUDO|F_DISABLED|F_WEAK,
373226031Sstas    DES_PCBC_encrypt_key_ivec,
374226031Sstas    0,
375226031Sstas    NULL
376226031Sstas};
377226031Sstas#endif /* HEIM_WEAK_CRYPTO */
378