]>
Commit | Line | Data |
---|---|---|
57ae2e24 | 1 | /* crypto/evp/e_des3.c */ |
58964a49 | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
d02b48c6 RE |
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. | |
0f113f3e | 8 | * |
d02b48c6 RE |
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). | |
0f113f3e | 15 | * |
d02b48c6 RE |
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. | |
0f113f3e | 22 | * |
d02b48c6 RE |
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 :-). | |
0f113f3e | 37 | * 4. If you include any Windows specific code (or a derivative thereof) from |
d02b48c6 RE |
38 | * the apps directory (application code) you must include an acknowledgement: |
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | |
0f113f3e | 40 | * |
d02b48c6 RE |
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. | |
0f113f3e | 52 | * |
d02b48c6 RE |
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" | |
9e9e8cb6 | 61 | #ifndef OPENSSL_NO_DES |
0f113f3e MC |
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 | typedef struct { | |
69 | union { | |
70 | double align; | |
71 | DES_key_schedule ks[3]; | |
72 | } ks; | |
73 | union { | |
74 | void (*cbc) (const void *, void *, size_t, const void *, void *); | |
75 | } stream; | |
76 | } DES_EDE_KEY; | |
77 | # define ks1 ks.ks[0] | |
78 | # define ks2 ks.ks[1] | |
79 | # define ks3 ks.ks[2] | |
80 | ||
81 | # if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__)) | |
c5d975a7 AP |
82 | /* ---------^^^ this is not a typo, just a way to detect that |
83 | * assembler support was in general requested... */ | |
0f113f3e | 84 | # include "sparc_arch.h" |
c5d975a7 AP |
85 | |
86 | extern unsigned int OPENSSL_sparcv9cap_P[]; | |
87 | ||
0f113f3e | 88 | # define SPARC_DES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_DES) |
c5d975a7 | 89 | |
0f113f3e MC |
90 | void des_t4_key_expand(const void *key, DES_key_schedule *ks); |
91 | void des_t4_ede3_cbc_encrypt(const void *inp, void *out, size_t len, | |
92 | DES_key_schedule *ks, unsigned char iv[8]); | |
93 | void des_t4_ede3_cbc_decrypt(const void *inp, void *out, size_t len, | |
94 | DES_key_schedule *ks, unsigned char iv[8]); | |
95 | # endif | |
c5d975a7 | 96 | |
1921eaad | 97 | static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, |
0f113f3e | 98 | const unsigned char *iv, int enc); |
57ae2e24 | 99 | |
1921eaad | 100 | static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, |
0f113f3e | 101 | const unsigned char *iv, int enc); |
d02b48c6 | 102 | |
216659eb DSH |
103 | static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); |
104 | ||
0f113f3e | 105 | # define data(ctx) ((DES_EDE_KEY *)(ctx)->cipher_data) |
dbad1690 | 106 | |
0f113f3e MC |
107 | /* |
108 | * Because of various casts and different args can't use | |
109 | * IMPLEMENT_BLOCK_CIPHER | |
110 | */ | |
d02b48c6 | 111 | |
1921eaad | 112 | static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, |
0f113f3e | 113 | const unsigned char *in, size_t inl) |
57ae2e24 | 114 | { |
0f113f3e MC |
115 | BLOCK_CIPHER_ecb_loop() |
116 | DES_ecb3_encrypt((const_DES_cblock *)(in + i), | |
117 | (DES_cblock *)(out + i), | |
118 | &data(ctx)->ks1, &data(ctx)->ks2, | |
119 | &data(ctx)->ks3, ctx->encrypt); | |
120 | return 1; | |
57ae2e24 DSH |
121 | } |
122 | ||
1921eaad | 123 | static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, |
0f113f3e | 124 | const unsigned char *in, size_t inl) |
57ae2e24 | 125 | { |
0f113f3e MC |
126 | while (inl >= EVP_MAXCHUNK) { |
127 | DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, | |
128 | &data(ctx)->ks1, &data(ctx)->ks2, | |
129 | &data(ctx)->ks3, (DES_cblock *)ctx->iv, | |
130 | &ctx->num); | |
131 | inl -= EVP_MAXCHUNK; | |
132 | in += EVP_MAXCHUNK; | |
133 | out += EVP_MAXCHUNK; | |
134 | } | |
135 | if (inl) | |
136 | DES_ede3_ofb64_encrypt(in, out, (long)inl, | |
137 | &data(ctx)->ks1, &data(ctx)->ks2, | |
138 | &data(ctx)->ks3, (DES_cblock *)ctx->iv, | |
139 | &ctx->num); | |
140 | ||
141 | return 1; | |
57ae2e24 DSH |
142 | } |
143 | ||
1921eaad | 144 | static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, |
0f113f3e | 145 | const unsigned char *in, size_t inl) |
57ae2e24 | 146 | { |
0f113f3e | 147 | DES_EDE_KEY *dat = data(ctx); |
c5d975a7 | 148 | |
0f113f3e MC |
149 | if (dat->stream.cbc) { |
150 | (*dat->stream.cbc) (in, out, inl, &dat->ks, ctx->iv); | |
151 | return 1; | |
152 | } | |
153 | ||
154 | while (inl >= EVP_MAXCHUNK) { | |
155 | DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, | |
156 | &dat->ks1, &dat->ks2, &dat->ks3, | |
b444ac3e | 157 | (DES_cblock *)ctx->iv, ctx->encrypt); |
0f113f3e MC |
158 | inl -= EVP_MAXCHUNK; |
159 | in += EVP_MAXCHUNK; | |
160 | out += EVP_MAXCHUNK; | |
161 | } | |
162 | if (inl) | |
163 | DES_ede3_cbc_encrypt(in, out, (long)inl, | |
164 | &dat->ks1, &dat->ks2, &dat->ks3, | |
165 | (DES_cblock *)ctx->iv, ctx->encrypt); | |
166 | return 1; | |
57ae2e24 DSH |
167 | } |
168 | ||
8c6336b0 | 169 | static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, |
0f113f3e | 170 | const unsigned char *in, size_t inl) |
57ae2e24 | 171 | { |
0f113f3e MC |
172 | while (inl >= EVP_MAXCHUNK) { |
173 | DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, | |
174 | &data(ctx)->ks1, &data(ctx)->ks2, | |
175 | &data(ctx)->ks3, (DES_cblock *)ctx->iv, | |
176 | &ctx->num, ctx->encrypt); | |
177 | inl -= EVP_MAXCHUNK; | |
178 | in += EVP_MAXCHUNK; | |
179 | out += EVP_MAXCHUNK; | |
180 | } | |
181 | if (inl) | |
182 | DES_ede3_cfb64_encrypt(in, out, (long)inl, | |
183 | &data(ctx)->ks1, &data(ctx)->ks2, | |
184 | &data(ctx)->ks3, (DES_cblock *)ctx->iv, | |
185 | &ctx->num, ctx->encrypt); | |
186 | return 1; | |
57ae2e24 DSH |
187 | } |
188 | ||
0f113f3e MC |
189 | /* |
190 | * Although we have a CFB-r implementation for 3-DES, it doesn't pack the | |
191 | * right way, so wrap it here | |
192 | */ | |
8c6336b0 | 193 | static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, |
0f113f3e MC |
194 | const unsigned char *in, size_t inl) |
195 | { | |
b444ac3e | 196 | size_t n; |
0f113f3e MC |
197 | unsigned char c[1], d[1]; |
198 | ||
199 | for (n = 0; n < inl; ++n) { | |
200 | c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; | |
201 | DES_ede3_cfb_encrypt(c, d, 1, 1, | |
202 | &data(ctx)->ks1, &data(ctx)->ks2, | |
203 | &data(ctx)->ks3, (DES_cblock *)ctx->iv, | |
204 | ctx->encrypt); | |
205 | out[n / 8] = (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) | |
206 | | ((d[0] & 0x80) >> (unsigned int)(n % 8)); | |
207 | } | |
8c6336b0 AP |
208 | |
209 | return 1; | |
0f113f3e | 210 | } |
8c6336b0 AP |
211 | |
212 | static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | |
0f113f3e MC |
213 | const unsigned char *in, size_t inl) |
214 | { | |
215 | while (inl >= EVP_MAXCHUNK) { | |
216 | DES_ede3_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK, | |
217 | &data(ctx)->ks1, &data(ctx)->ks2, | |
218 | &data(ctx)->ks3, (DES_cblock *)ctx->iv, | |
219 | ctx->encrypt); | |
220 | inl -= EVP_MAXCHUNK; | |
221 | in += EVP_MAXCHUNK; | |
222 | out += EVP_MAXCHUNK; | |
223 | } | |
b444ac3e | 224 | if (inl) |
0f113f3e MC |
225 | DES_ede3_cfb_encrypt(in, out, 8, (long)inl, |
226 | &data(ctx)->ks1, &data(ctx)->ks2, | |
227 | &data(ctx)->ks3, (DES_cblock *)ctx->iv, | |
228 | ctx->encrypt); | |
8c6336b0 | 229 | return 1; |
0f113f3e | 230 | } |
8c6336b0 | 231 | |
a6cd8707 | 232 | BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64, |
0f113f3e MC |
233 | EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_DEFAULT_ASN1, |
234 | des_ede_init_key, NULL, NULL, NULL, des3_ctrl) | |
235 | # define des_ede3_cfb64_cipher des_ede_cfb64_cipher | |
236 | # define des_ede3_ofb_cipher des_ede_ofb_cipher | |
237 | # define des_ede3_cbc_cipher des_ede_cbc_cipher | |
238 | # define des_ede3_ecb_cipher des_ede_ecb_cipher | |
239 | BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64, | |
240 | EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_DEFAULT_ASN1, | |
241 | des_ede3_init_key, NULL, NULL, NULL, des3_ctrl) | |
242 | ||
243 | BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 1, | |
244 | EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_DEFAULT_ASN1, | |
245 | des_ede3_init_key, NULL, NULL, NULL, des3_ctrl) | |
246 | ||
247 | BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 8, | |
248 | EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_DEFAULT_ASN1, | |
249 | des_ede3_init_key, NULL, NULL, NULL, des3_ctrl) | |
8c6336b0 | 250 | |
1921eaad | 251 | static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, |
0f113f3e MC |
252 | const unsigned char *iv, int enc) |
253 | { | |
254 | DES_cblock *deskey = (DES_cblock *)key; | |
255 | DES_EDE_KEY *dat = data(ctx); | |
256 | ||
257 | dat->stream.cbc = NULL; | |
258 | # if defined(SPARC_DES_CAPABLE) | |
259 | if (SPARC_DES_CAPABLE) { | |
260 | int mode = ctx->cipher->flags & EVP_CIPH_MODE; | |
261 | ||
262 | if (mode == EVP_CIPH_CBC_MODE) { | |
263 | des_t4_key_expand(&deskey[0], &dat->ks1); | |
264 | des_t4_key_expand(&deskey[1], &dat->ks2); | |
265 | memcpy(&dat->ks3, &dat->ks1, sizeof(dat->ks1)); | |
266 | dat->stream.cbc = enc ? des_t4_ede3_cbc_encrypt : | |
267 | des_t4_ede3_cbc_decrypt; | |
268 | return 1; | |
269 | } | |
270 | } | |
271 | # endif | |
272 | # ifdef EVP_CHECK_DES_KEY | |
273 | if (DES_set_key_checked(&deskey[0], &dat->ks1) | |
274 | ! !DES_set_key_checked(&deskey[1], &dat->ks2)) | |
275 | return 0; | |
276 | # else | |
277 | DES_set_key_unchecked(&deskey[0], &dat->ks1); | |
278 | DES_set_key_unchecked(&deskey[1], &dat->ks2); | |
279 | # endif | |
280 | memcpy(&dat->ks3, &dat->ks1, sizeof(dat->ks1)); | |
281 | return 1; | |
282 | } | |
d02b48c6 | 283 | |
1921eaad | 284 | static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, |
0f113f3e MC |
285 | const unsigned char *iv, int enc) |
286 | { | |
287 | DES_cblock *deskey = (DES_cblock *)key; | |
288 | DES_EDE_KEY *dat = data(ctx); | |
c5d975a7 | 289 | |
0f113f3e MC |
290 | dat->stream.cbc = NULL; |
291 | # if defined(SPARC_DES_CAPABLE) | |
292 | if (SPARC_DES_CAPABLE) { | |
293 | int mode = ctx->cipher->flags & EVP_CIPH_MODE; | |
294 | ||
295 | if (mode == EVP_CIPH_CBC_MODE) { | |
296 | des_t4_key_expand(&deskey[0], &dat->ks1); | |
297 | des_t4_key_expand(&deskey[1], &dat->ks2); | |
298 | des_t4_key_expand(&deskey[2], &dat->ks3); | |
299 | dat->stream.cbc = enc ? des_t4_ede3_cbc_encrypt : | |
300 | des_t4_ede3_cbc_decrypt; | |
301 | return 1; | |
302 | } | |
303 | } | |
304 | # endif | |
305 | # ifdef EVP_CHECK_DES_KEY | |
306 | if (DES_set_key_checked(&deskey[0], &dat->ks1) | |
307 | || DES_set_key_checked(&deskey[1], &dat->ks2) | |
308 | || DES_set_key_checked(&deskey[2], &dat->ks3)) | |
309 | return 0; | |
310 | # else | |
311 | DES_set_key_unchecked(&deskey[0], &dat->ks1); | |
312 | DES_set_key_unchecked(&deskey[1], &dat->ks2); | |
313 | DES_set_key_unchecked(&deskey[2], &dat->ks3); | |
314 | # endif | |
315 | return 1; | |
316 | } | |
57ae2e24 | 317 | |
216659eb | 318 | static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) |
0f113f3e MC |
319 | { |
320 | ||
321 | DES_cblock *deskey = ptr; | |
322 | ||
323 | switch (type) { | |
324 | case EVP_CTRL_RAND_KEY: | |
325 | if (RAND_bytes(ptr, c->key_len) <= 0) | |
326 | return 0; | |
327 | DES_set_odd_parity(deskey); | |
328 | if (c->key_len >= 16) | |
329 | DES_set_odd_parity(deskey + 1); | |
330 | if (c->key_len >= 24) | |
331 | DES_set_odd_parity(deskey + 2); | |
332 | return 1; | |
333 | ||
334 | default: | |
335 | return -1; | |
336 | } | |
337 | } | |
216659eb | 338 | |
13588350 | 339 | const EVP_CIPHER *EVP_des_ede(void) |
57ae2e24 | 340 | { |
0f113f3e | 341 | return &des_ede_ecb; |
57ae2e24 DSH |
342 | } |
343 | ||
13588350 | 344 | const EVP_CIPHER *EVP_des_ede3(void) |
57ae2e24 | 345 | { |
0f113f3e | 346 | return &des_ede3_ecb; |
57ae2e24 | 347 | } |
97cf1f6c | 348 | |
97cf1f6c | 349 | |
474e469b | 350 | # include <openssl/sha.h> |
97cf1f6c | 351 | |
0f113f3e MC |
352 | static const unsigned char wrap_iv[8] = |
353 | { 0x4a, 0xdd, 0xa2, 0x2c, 0x79, 0xe8, 0x21, 0x05 }; | |
97cf1f6c DSH |
354 | |
355 | static int des_ede3_unwrap(EVP_CIPHER_CTX *ctx, unsigned char *out, | |
0f113f3e MC |
356 | const unsigned char *in, size_t inl) |
357 | { | |
358 | unsigned char icv[8], iv[8], sha1tmp[SHA_DIGEST_LENGTH]; | |
359 | int rv = -1; | |
360 | if (inl < 24) | |
361 | return -1; | |
362 | if (!out) | |
363 | return inl - 16; | |
364 | memcpy(ctx->iv, wrap_iv, 8); | |
365 | /* Decrypt first block which will end up as icv */ | |
366 | des_ede_cbc_cipher(ctx, icv, in, 8); | |
367 | /* Decrypt central blocks */ | |
368 | /* | |
369 | * If decrypting in place move whole output along a block so the next | |
370 | * des_ede_cbc_cipher is in place. | |
371 | */ | |
372 | if (out == in) { | |
373 | memmove(out, out + 8, inl - 8); | |
374 | in -= 8; | |
375 | } | |
376 | des_ede_cbc_cipher(ctx, out, in + 8, inl - 16); | |
377 | /* Decrypt final block which will be IV */ | |
378 | des_ede_cbc_cipher(ctx, iv, in + inl - 8, 8); | |
379 | /* Reverse order of everything */ | |
380 | BUF_reverse(icv, NULL, 8); | |
381 | BUF_reverse(out, NULL, inl - 16); | |
382 | BUF_reverse(ctx->iv, iv, 8); | |
383 | /* Decrypt again using new IV */ | |
384 | des_ede_cbc_cipher(ctx, out, out, inl - 16); | |
385 | des_ede_cbc_cipher(ctx, icv, icv, 8); | |
386 | /* Work out SHA1 hash of first portion */ | |
387 | SHA1(out, inl - 16, sha1tmp); | |
388 | ||
389 | if (!CRYPTO_memcmp(sha1tmp, icv, 8)) | |
390 | rv = inl - 16; | |
391 | OPENSSL_cleanse(icv, 8); | |
392 | OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH); | |
393 | OPENSSL_cleanse(iv, 8); | |
394 | OPENSSL_cleanse(ctx->iv, 8); | |
395 | if (rv == -1) | |
396 | OPENSSL_cleanse(out, inl - 16); | |
397 | ||
398 | return rv; | |
399 | } | |
97cf1f6c DSH |
400 | |
401 | static int des_ede3_wrap(EVP_CIPHER_CTX *ctx, unsigned char *out, | |
0f113f3e MC |
402 | const unsigned char *in, size_t inl) |
403 | { | |
404 | unsigned char sha1tmp[SHA_DIGEST_LENGTH]; | |
405 | if (!out) | |
406 | return inl + 16; | |
407 | /* Copy input to output buffer + 8 so we have space for IV */ | |
408 | memmove(out + 8, in, inl); | |
409 | /* Work out ICV */ | |
410 | SHA1(in, inl, sha1tmp); | |
411 | memcpy(out + inl + 8, sha1tmp, 8); | |
412 | OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH); | |
413 | /* Generate random IV */ | |
266483d2 MC |
414 | if (RAND_bytes(ctx->iv, 8) <= 0) |
415 | return -1; | |
0f113f3e MC |
416 | memcpy(out, ctx->iv, 8); |
417 | /* Encrypt everything after IV in place */ | |
418 | des_ede_cbc_cipher(ctx, out + 8, out + 8, inl + 8); | |
419 | BUF_reverse(out, NULL, inl + 16); | |
420 | memcpy(ctx->iv, wrap_iv, 8); | |
421 | des_ede_cbc_cipher(ctx, out, out, inl + 16); | |
422 | return inl + 16; | |
423 | } | |
97cf1f6c DSH |
424 | |
425 | static int des_ede3_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | |
0f113f3e MC |
426 | const unsigned char *in, size_t inl) |
427 | { | |
428 | /* | |
429 | * Sanity check input length: we typically only wrap keys so EVP_MAXCHUNK | |
430 | * is more than will ever be needed. Also input length must be a multiple | |
431 | * of 8 bits. | |
432 | */ | |
433 | if (inl >= EVP_MAXCHUNK || inl % 8) | |
434 | return -1; | |
435 | if (ctx->encrypt) | |
436 | return des_ede3_wrap(ctx, out, in, inl); | |
437 | else | |
438 | return des_ede3_unwrap(ctx, out, in, inl); | |
439 | } | |
97cf1f6c DSH |
440 | |
441 | static const EVP_CIPHER des3_wrap = { | |
0f113f3e MC |
442 | NID_id_smime_alg_CMS3DESwrap, |
443 | 8, 24, 0, | |
444 | EVP_CIPH_WRAP_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER | |
445 | | EVP_CIPH_FLAG_DEFAULT_ASN1, | |
446 | des_ede3_init_key, des_ede3_wrap_cipher, | |
447 | NULL, | |
448 | sizeof(DES_EDE_KEY), | |
449 | NULL, NULL, NULL, NULL | |
450 | }; | |
97cf1f6c DSH |
451 | |
452 | const EVP_CIPHER *EVP_des_ede3_wrap(void) | |
0f113f3e MC |
453 | { |
454 | return &des3_wrap; | |
455 | } | |
97cf1f6c | 456 | |
d02f751c | 457 | #endif |