1 |
/* crypto/evp/e_des3.c */ |
2 |
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 |
* All rights reserved. |
4 |
* |
5 |
* This package is an SSL implementation written |
6 |
* by Eric Young (eay@cryptsoft.com). |
7 |
* The implementation was written so as to conform with Netscapes SSL. |
8 |
* |
9 |
* This library is free for commercial and non-commercial use as long as |
10 |
* the following conditions are aheared to. The following conditions |
11 |
* apply to all code found in this distribution, be it the RC4, RSA, |
12 |
* lhash, DES, etc., code; not just the SSL code. The SSL documentation |
13 |
* included with this distribution is covered by the same copyright terms |
14 |
* except that the holder is Tim Hudson (tjh@cryptsoft.com). |
15 |
* |
16 |
* Copyright remains Eric Young's, and as such any Copyright notices in |
17 |
* the code are not to be removed. |
18 |
* If this package is used in a product, Eric Young should be given attribution |
19 |
* as the author of the parts of the library used. |
20 |
* This can be in the form of a textual message at program startup or |
21 |
* in documentation (online or textual) provided with the package. |
22 |
* |
23 |
* Redistribution and use in source and binary forms, with or without |
24 |
* modification, are permitted provided that the following conditions |
25 |
* are met: |
26 |
* 1. Redistributions of source code must retain the copyright |
27 |
* notice, this list of conditions and the following disclaimer. |
28 |
* 2. Redistributions in binary form must reproduce the above copyright |
29 |
* notice, this list of conditions and the following disclaimer in the |
30 |
* documentation and/or other materials provided with the distribution. |
31 |
* 3. All advertising materials mentioning features or use of this software |
32 |
* must display the following acknowledgement: |
33 |
* "This product includes cryptographic software written by |
34 |
* Eric Young (eay@cryptsoft.com)" |
35 |
* The word 'cryptographic' can be left out if the rouines from the library |
36 |
* being used are not cryptographic related :-). |
37 |
* 4. If you include any Windows specific code (or a derivative thereof) from |
38 |
* the apps directory (application code) you must include an acknowledgement: |
39 |
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" |
40 |
* |
41 |
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND |
42 |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
43 |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
44 |
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
45 |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
46 |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
47 |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
48 |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
49 |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
50 |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
51 |
* SUCH DAMAGE. |
52 |
* |
53 |
* The licence and distribution terms for any publically available version or |
54 |
* derivative of this code cannot be changed. i.e. this code cannot simply be |
55 |
* copied and put under another distribution licence |
56 |
* [including the GNU Public Licence.] |
57 |
*/ |
58 |
|
59 |
#include <stdio.h> |
60 |
#include "cryptlib.h" |
61 |
#ifndef OPENSSL_NO_DES |
62 |
# include <openssl/evp.h> |
63 |
# include <openssl/objects.h> |
64 |
# include "evp_locl.h" |
65 |
# include <openssl/des.h> |
66 |
# include <openssl/rand.h> |
67 |
|
68 |
# ifndef OPENSSL_FIPS |
69 |
|
70 |
static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, |
71 |
const unsigned char *iv, int enc); |
72 |
|
73 |
static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, |
74 |
const unsigned char *iv, int enc); |
75 |
|
76 |
static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); |
77 |
|
78 |
typedef struct { |
79 |
DES_key_schedule ks1; /* key schedule */ |
80 |
DES_key_schedule ks2; /* key schedule (for ede) */ |
81 |
DES_key_schedule ks3; /* key schedule (for ede3) */ |
82 |
} DES_EDE_KEY; |
83 |
|
84 |
# define data(ctx) ((DES_EDE_KEY *)(ctx)->cipher_data) |
85 |
|
86 |
/* |
87 |
* Because of various casts and different args can't use |
88 |
* IMPLEMENT_BLOCK_CIPHER |
89 |
*/ |
90 |
|
91 |
static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, |
92 |
const unsigned char *in, size_t inl) |
93 |
{ |
94 |
BLOCK_CIPHER_ecb_loop() |
95 |
DES_ecb3_encrypt((const_DES_cblock *)(in + i), |
96 |
(DES_cblock *)(out + i), |
97 |
&data(ctx)->ks1, &data(ctx)->ks2, |
98 |
&data(ctx)->ks3, ctx->encrypt); |
99 |
return 1; |
100 |
} |
101 |
|
102 |
static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, |
103 |
const unsigned char *in, size_t inl) |
104 |
{ |
105 |
while (inl >= EVP_MAXCHUNK) { |
106 |
DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, |
107 |
&data(ctx)->ks1, &data(ctx)->ks2, |
108 |
&data(ctx)->ks3, (DES_cblock *)ctx->iv, |
109 |
&ctx->num); |
110 |
inl -= EVP_MAXCHUNK; |
111 |
in += EVP_MAXCHUNK; |
112 |
out += EVP_MAXCHUNK; |
113 |
} |
114 |
if (inl) |
115 |
DES_ede3_ofb64_encrypt(in, out, (long)inl, |
116 |
&data(ctx)->ks1, &data(ctx)->ks2, |
117 |
&data(ctx)->ks3, (DES_cblock *)ctx->iv, |
118 |
&ctx->num); |
119 |
|
120 |
return 1; |
121 |
} |
122 |
|
123 |
static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, |
124 |
const unsigned char *in, size_t inl) |
125 |
{ |
126 |
# ifdef KSSL_DEBUG |
127 |
{ |
128 |
int i; |
129 |
fprintf(stderr, "des_ede_cbc_cipher(ctx=%p, buflen=%d)\n", ctx, |
130 |
ctx->buf_len); |
131 |
fprintf(stderr, "\t iv= "); |
132 |
for (i = 0; i < 8; i++) |
133 |
fprintf(stderr, "%02X", ctx->iv[i]); |
134 |
fprintf(stderr, "\n"); |
135 |
} |
136 |
# endif /* KSSL_DEBUG */ |
137 |
while (inl >= EVP_MAXCHUNK) { |
138 |
DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, |
139 |
&data(ctx)->ks1, &data(ctx)->ks2, |
140 |
&data(ctx)->ks3, (DES_cblock *)ctx->iv, |
141 |
ctx->encrypt); |
142 |
inl -= EVP_MAXCHUNK; |
143 |
in += EVP_MAXCHUNK; |
144 |
out += EVP_MAXCHUNK; |
145 |
} |
146 |
if (inl) |
147 |
DES_ede3_cbc_encrypt(in, out, (long)inl, |
148 |
&data(ctx)->ks1, &data(ctx)->ks2, |
149 |
&data(ctx)->ks3, (DES_cblock *)ctx->iv, |
150 |
ctx->encrypt); |
151 |
return 1; |
152 |
} |
153 |
|
154 |
static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, |
155 |
const unsigned char *in, size_t inl) |
156 |
{ |
157 |
while (inl >= EVP_MAXCHUNK) { |
158 |
DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, |
159 |
&data(ctx)->ks1, &data(ctx)->ks2, |
160 |
&data(ctx)->ks3, (DES_cblock *)ctx->iv, |
161 |
&ctx->num, ctx->encrypt); |
162 |
inl -= EVP_MAXCHUNK; |
163 |
in += EVP_MAXCHUNK; |
164 |
out += EVP_MAXCHUNK; |
165 |
} |
166 |
if (inl) |
167 |
DES_ede3_cfb64_encrypt(in, out, (long)inl, |
168 |
&data(ctx)->ks1, &data(ctx)->ks2, |
169 |
&data(ctx)->ks3, (DES_cblock *)ctx->iv, |
170 |
&ctx->num, ctx->encrypt); |
171 |
return 1; |
172 |
} |
173 |
|
174 |
/* |
175 |
* Although we have a CFB-r implementation for 3-DES, it doesn't pack the |
176 |
* right way, so wrap it here |
177 |
*/ |
178 |
static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, |
179 |
const unsigned char *in, size_t inl) |
180 |
{ |
181 |
size_t n; |
182 |
unsigned char c[1], d[1]; |
183 |
|
184 |
for (n = 0; n < inl; ++n) { |
185 |
c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; |
186 |
DES_ede3_cfb_encrypt(c, d, 1, 1, |
187 |
&data(ctx)->ks1, &data(ctx)->ks2, |
188 |
&data(ctx)->ks3, (DES_cblock *)ctx->iv, |
189 |
ctx->encrypt); |
190 |
out[n / 8] = (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) |
191 |
| ((d[0] & 0x80) >> (unsigned int)(n % 8)); |
192 |
} |
193 |
|
194 |
return 1; |
195 |
} |
196 |
|
197 |
static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, |
198 |
const unsigned char *in, size_t inl) |
199 |
{ |
200 |
while (inl >= EVP_MAXCHUNK) { |
201 |
DES_ede3_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK, |
202 |
&data(ctx)->ks1, &data(ctx)->ks2, |
203 |
&data(ctx)->ks3, (DES_cblock *)ctx->iv, |
204 |
ctx->encrypt); |
205 |
inl -= EVP_MAXCHUNK; |
206 |
in += EVP_MAXCHUNK; |
207 |
out += EVP_MAXCHUNK; |
208 |
} |
209 |
if (inl) |
210 |
DES_ede3_cfb_encrypt(in, out, 8, (long)inl, |
211 |
&data(ctx)->ks1, &data(ctx)->ks2, |
212 |
&data(ctx)->ks3, (DES_cblock *)ctx->iv, |
213 |
ctx->encrypt); |
214 |
return 1; |
215 |
} |
216 |
|
217 |
BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64, |
218 |
EVP_CIPH_RAND_KEY, des_ede_init_key, NULL, |
219 |
EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des3_ctrl) |
220 |
# define des_ede3_cfb64_cipher des_ede_cfb64_cipher |
221 |
# define des_ede3_ofb_cipher des_ede_ofb_cipher |
222 |
# define des_ede3_cbc_cipher des_ede_cbc_cipher |
223 |
# define des_ede3_ecb_cipher des_ede_ecb_cipher |
224 |
BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64, |
225 |
EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL, |
226 |
EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des3_ctrl) |
227 |
|
228 |
BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 1, |
229 |
EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL, |
230 |
EVP_CIPHER_set_asn1_iv, |
231 |
EVP_CIPHER_get_asn1_iv, des3_ctrl) |
232 |
|
233 |
BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 8, |
234 |
EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL, |
235 |
EVP_CIPHER_set_asn1_iv, |
236 |
EVP_CIPHER_get_asn1_iv, des3_ctrl) |
237 |
|
238 |
static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, |
239 |
const unsigned char *iv, int enc) |
240 |
{ |
241 |
DES_cblock *deskey = (DES_cblock *)key; |
242 |
# ifdef EVP_CHECK_DES_KEY |
243 |
if (DES_set_key_checked(&deskey[0], &data(ctx)->ks1) |
244 |
|| DES_set_key_checked(&deskey[1], &data(ctx)->ks2)) |
245 |
return 0; |
246 |
# else |
247 |
DES_set_key_unchecked(&deskey[0], &data(ctx)->ks1); |
248 |
DES_set_key_unchecked(&deskey[1], &data(ctx)->ks2); |
249 |
# endif |
250 |
memcpy(&data(ctx)->ks3, &data(ctx)->ks1, sizeof(data(ctx)->ks1)); |
251 |
return 1; |
252 |
} |
253 |
|
254 |
static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, |
255 |
const unsigned char *iv, int enc) |
256 |
{ |
257 |
DES_cblock *deskey = (DES_cblock *)key; |
258 |
# ifdef KSSL_DEBUG |
259 |
{ |
260 |
int i; |
261 |
fprintf(stderr, "des_ede3_init_key(ctx=%p)\n", ctx); |
262 |
fprintf(stderr, "\tKEY= "); |
263 |
for (i = 0; i < 24; i++) |
264 |
fprintf(stderr, "%02X", key[i]); |
265 |
fprintf(stderr, "\n"); |
266 |
if (iv) { |
267 |
fprintf(stderr, "\t IV= "); |
268 |
for (i = 0; i < 8; i++) |
269 |
fprintf(stderr, "%02X", iv[i]); |
270 |
fprintf(stderr, "\n"); |
271 |
} |
272 |
} |
273 |
# endif /* KSSL_DEBUG */ |
274 |
|
275 |
# ifdef EVP_CHECK_DES_KEY |
276 |
if (DES_set_key_checked(&deskey[0], &data(ctx)->ks1) |
277 |
|| DES_set_key_checked(&deskey[1], &data(ctx)->ks2) |
278 |
|| DES_set_key_checked(&deskey[2], &data(ctx)->ks3)) |
279 |
return 0; |
280 |
# else |
281 |
DES_set_key_unchecked(&deskey[0], &data(ctx)->ks1); |
282 |
DES_set_key_unchecked(&deskey[1], &data(ctx)->ks2); |
283 |
DES_set_key_unchecked(&deskey[2], &data(ctx)->ks3); |
284 |
# endif |
285 |
return 1; |
286 |
} |
287 |
|
288 |
static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) |
289 |
{ |
290 |
|
291 |
DES_cblock *deskey = ptr; |
292 |
|
293 |
switch (type) { |
294 |
case EVP_CTRL_RAND_KEY: |
295 |
if (RAND_bytes(ptr, c->key_len) <= 0) |
296 |
return 0; |
297 |
DES_set_odd_parity(deskey); |
298 |
if (c->key_len >= 16) |
299 |
DES_set_odd_parity(deskey + 1); |
300 |
if (c->key_len >= 24) |
301 |
DES_set_odd_parity(deskey + 2); |
302 |
return 1; |
303 |
|
304 |
default: |
305 |
return -1; |
306 |
} |
307 |
} |
308 |
|
309 |
const EVP_CIPHER *EVP_des_ede(void) |
310 |
{ |
311 |
return &des_ede_ecb; |
312 |
} |
313 |
|
314 |
const EVP_CIPHER *EVP_des_ede3(void) |
315 |
{ |
316 |
return &des_ede3_ecb; |
317 |
} |
318 |
# endif |
319 |
#endif |