Import of code from heimdal
[openafs.git] / src / external / heimdal / krb5 / crypto-des3.c
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 /*
37  *
38  */
39
40 static void
41 DES3_random_key(krb5_context context,
42                 krb5_keyblock *key)
43 {
44     DES_cblock *k = key->keyvalue.data;
45     do {
46         krb5_generate_random_block(k, 3 * sizeof(DES_cblock));
47         DES_set_odd_parity(&k[0]);
48         DES_set_odd_parity(&k[1]);
49         DES_set_odd_parity(&k[2]);
50     } while(DES_is_weak_key(&k[0]) ||
51             DES_is_weak_key(&k[1]) ||
52             DES_is_weak_key(&k[2]));
53 }
54
55
56 #ifdef DES3_OLD_ENCTYPE
57 static struct _krb5_key_type keytype_des3 = {
58     ETYPE_OLD_DES3_CBC_SHA1,
59     "des3",
60     168,
61     24,
62     sizeof(struct _krb5_evp_schedule),
63     DES3_random_key,
64     _krb5_evp_schedule,
65     _krb5_des3_salt,
66     _krb5_DES3_random_to_key,
67     _krb5_evp_cleanup,
68     EVP_des_ede3_cbc
69 };
70 #endif
71
72 static struct _krb5_key_type keytype_des3_derived = {
73     ETYPE_OLD_DES3_CBC_SHA1,
74     "des3",
75     168,
76     24,
77     sizeof(struct _krb5_evp_schedule),
78     DES3_random_key,
79     _krb5_evp_schedule,
80     _krb5_des3_salt_derived,
81     _krb5_DES3_random_to_key,
82     _krb5_evp_cleanup,
83     EVP_des_ede3_cbc
84 };
85
86 #ifdef DES3_OLD_ENCTYPE
87 static krb5_error_code
88 RSA_MD5_DES3_checksum(krb5_context context,
89                       struct _krb5_key_data *key,
90                       const void *data,
91                       size_t len,
92                       unsigned usage,
93                       Checksum *C)
94 {
95     return _krb5_des_checksum(context, EVP_md5(), key, data, len, C);
96 }
97
98 static krb5_error_code
99 RSA_MD5_DES3_verify(krb5_context context,
100                     struct _krb5_key_data *key,
101                     const void *data,
102                     size_t len,
103                     unsigned usage,
104                     Checksum *C)
105 {
106     return _krb5_des_verify(context, EVP_md5(), key, data, len, C);
107 }
108
109 struct _krb5_checksum_type _krb5_checksum_rsa_md5_des3 = {
110     CKSUMTYPE_RSA_MD5_DES3,
111     "rsa-md5-des3",
112     64,
113     24,
114     F_KEYED | F_CPROOF | F_VARIANT,
115     RSA_MD5_DES3_checksum,
116     RSA_MD5_DES3_verify
117 };
118 #endif
119
120 struct _krb5_checksum_type _krb5_checksum_hmac_sha1_des3 = {
121     CKSUMTYPE_HMAC_SHA1_DES3,
122     "hmac-sha1-des3",
123     64,
124     20,
125     F_KEYED | F_CPROOF | F_DERIVED,
126     _krb5_SP_HMAC_SHA1_checksum,
127     NULL
128 };
129
130 #ifdef DES3_OLD_ENCTYPE
131 struct _krb5_encryption_type _krb5_enctype_des3_cbc_md5 = {
132     ETYPE_DES3_CBC_MD5,
133     "des3-cbc-md5",
134     NULL,
135     8,
136     8,
137     8,
138     &keytype_des3,
139     &_krb5_checksum_rsa_md5,
140     &_krb5_checksum_rsa_md5_des3,
141     0,
142     _krb5_evp_encrypt,
143     0,
144     NULL
145 };
146 #endif
147
148 struct _krb5_encryption_type _krb5_enctype_des3_cbc_sha1 = {
149     ETYPE_DES3_CBC_SHA1,
150     "des3-cbc-sha1",
151     NULL,
152     8,
153     8,
154     8,
155     &keytype_des3_derived,
156     &_krb5_checksum_sha1,
157     &_krb5_checksum_hmac_sha1_des3,
158     F_DERIVED,
159     _krb5_evp_encrypt,
160     0,
161     NULL
162 };
163
164 #ifdef DES3_OLD_ENCTYPE
165 struct _krb5_encryption_type _krb5_enctype_old_des3_cbc_sha1 = {
166     ETYPE_OLD_DES3_CBC_SHA1,
167     "old-des3-cbc-sha1",
168     NULL,
169     8,
170     8,
171     8,
172     &keytype_des3,
173     &_krb5_checksum_sha1,
174     &_krb5_checksum_hmac_sha1_des3,
175     0,
176     _krb5_evp_encrypt,
177     0,
178     NULL
179 };
180 #endif
181
182 struct _krb5_encryption_type _krb5_enctype_des3_cbc_none = {
183     ETYPE_DES3_CBC_NONE,
184     "des3-cbc-none",
185     NULL,
186     8,
187     8,
188     0,
189     &keytype_des3_derived,
190     &_krb5_checksum_none,
191     NULL,
192     F_PSEUDO,
193     _krb5_evp_encrypt,
194     0,
195     NULL
196 };
197
198 void
199 _krb5_DES3_random_to_key(krb5_context context,
200                          krb5_keyblock *key,
201                          const void *data,
202                          size_t size)
203 {
204     unsigned char *x = key->keyvalue.data;
205     const u_char *q = data;
206     DES_cblock *k;
207     int i, j;
208
209     memset(key->keyvalue.data, 0, key->keyvalue.length);
210     for (i = 0; i < 3; ++i) {
211         unsigned char foo;
212         for (j = 0; j < 7; ++j) {
213             unsigned char b = q[7 * i + j];
214
215             x[8 * i + j] = b;
216         }
217         foo = 0;
218         for (j = 6; j >= 0; --j) {
219             foo |= q[7 * i + j] & 1;
220             foo <<= 1;
221         }
222         x[8 * i + 7] = foo;
223     }
224     k = key->keyvalue.data;
225     for (i = 0; i < 3; i++) {
226         DES_set_odd_parity(&k[i]);
227         if(DES_is_weak_key(&k[i]))
228             _krb5_xor(&k[i], (const unsigned char*)"\0\0\0\0\0\0\0\xf0");
229     }
230 }