168651Skris/* crypto/evp/e_des3.c */
268651Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
368651Skris * All rights reserved.
468651Skris *
568651Skris * This package is an SSL implementation written
668651Skris * by Eric Young (eay@cryptsoft.com).
768651Skris * The implementation was written so as to conform with Netscapes SSL.
8280304Sjkim *
968651Skris * This library is free for commercial and non-commercial use as long as
1068651Skris * the following conditions are aheared to.  The following conditions
1168651Skris * apply to all code found in this distribution, be it the RC4, RSA,
1268651Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1368651Skris * included with this distribution is covered by the same copyright terms
1468651Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15280304Sjkim *
1668651Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1768651Skris * the code are not to be removed.
1868651Skris * If this package is used in a product, Eric Young should be given attribution
1968651Skris * as the author of the parts of the library used.
2068651Skris * This can be in the form of a textual message at program startup or
2168651Skris * in documentation (online or textual) provided with the package.
22280304Sjkim *
2368651Skris * Redistribution and use in source and binary forms, with or without
2468651Skris * modification, are permitted provided that the following conditions
2568651Skris * are met:
2668651Skris * 1. Redistributions of source code must retain the copyright
2768651Skris *    notice, this list of conditions and the following disclaimer.
2868651Skris * 2. Redistributions in binary form must reproduce the above copyright
2968651Skris *    notice, this list of conditions and the following disclaimer in the
3068651Skris *    documentation and/or other materials provided with the distribution.
3168651Skris * 3. All advertising materials mentioning features or use of this software
3268651Skris *    must display the following acknowledgement:
3368651Skris *    "This product includes cryptographic software written by
3468651Skris *     Eric Young (eay@cryptsoft.com)"
3568651Skris *    The word 'cryptographic' can be left out if the rouines from the library
3668651Skris *    being used are not cryptographic related :-).
37280304Sjkim * 4. If you include any Windows specific code (or a derivative thereof) from
3868651Skris *    the apps directory (application code) you must include an acknowledgement:
3968651Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40280304Sjkim *
4168651Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4268651Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4368651Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4468651Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4568651Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4668651Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4768651Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4868651Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4968651Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5068651Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5168651Skris * SUCH DAMAGE.
52280304Sjkim *
5368651Skris * The licence and distribution terms for any publically available version or
5468651Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5568651Skris * copied and put under another distribution licence
5668651Skris * [including the GNU Public Licence.]
5768651Skris */
5868651Skris
5968651Skris#include <stdio.h>
6068651Skris#include "cryptlib.h"
61142425Snectar#ifndef OPENSSL_NO_DES
62280304Sjkim# include <openssl/evp.h>
63280304Sjkim# include <openssl/objects.h>
64280304Sjkim# include "evp_locl.h"
65280304Sjkim# include <openssl/des.h>
66280304Sjkim# include <openssl/rand.h>
6768651Skris
68280304Sjkim# ifndef OPENSSL_FIPS
69238405Sjkim
7068651Skrisstatic int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
71280304Sjkim                            const unsigned char *iv, int enc);
7268651Skris
7368651Skrisstatic int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
74280304Sjkim                             const unsigned char *iv, int enc);
7568651Skris
76160814Ssimonstatic int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
77160814Ssimon
78280304Sjkimtypedef struct {
79280304Sjkim    DES_key_schedule ks1;       /* key schedule */
80280304Sjkim    DES_key_schedule ks2;       /* key schedule (for ede) */
81280304Sjkim    DES_key_schedule ks3;       /* key schedule (for ede3) */
82280304Sjkim} DES_EDE_KEY;
83109998Smarkm
84280304Sjkim#  define data(ctx) ((DES_EDE_KEY *)(ctx)->cipher_data)
85109998Smarkm
86280304Sjkim/*
87280304Sjkim * Because of various casts and different args can't use
88280304Sjkim * IMPLEMENT_BLOCK_CIPHER
89280304Sjkim */
9068651Skris
9168651Skrisstatic int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
92280304Sjkim                              const unsigned char *in, size_t inl)
9368651Skris{
94280304Sjkim    BLOCK_CIPHER_ecb_loop()
95280304Sjkim        DES_ecb3_encrypt((const_DES_cblock *)(in + i),
96280304Sjkim                         (DES_cblock *)(out + i),
97280304Sjkim                         &data(ctx)->ks1, &data(ctx)->ks2,
98280304Sjkim                         &data(ctx)->ks3, ctx->encrypt);
99280304Sjkim    return 1;
10068651Skris}
10168651Skris
10268651Skrisstatic int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
103280304Sjkim                              const unsigned char *in, size_t inl)
10468651Skris{
105280304Sjkim    while (inl >= EVP_MAXCHUNK) {
106280304Sjkim        DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK,
107280304Sjkim                               &data(ctx)->ks1, &data(ctx)->ks2,
108280304Sjkim                               &data(ctx)->ks3, (DES_cblock *)ctx->iv,
109280304Sjkim                               &ctx->num);
110280304Sjkim        inl -= EVP_MAXCHUNK;
111280304Sjkim        in += EVP_MAXCHUNK;
112280304Sjkim        out += EVP_MAXCHUNK;
113280304Sjkim    }
114280304Sjkim    if (inl)
115280304Sjkim        DES_ede3_ofb64_encrypt(in, out, (long)inl,
116280304Sjkim                               &data(ctx)->ks1, &data(ctx)->ks2,
117280304Sjkim                               &data(ctx)->ks3, (DES_cblock *)ctx->iv,
118280304Sjkim                               &ctx->num);
119238405Sjkim
120280304Sjkim    return 1;
12168651Skris}
12268651Skris
12368651Skrisstatic int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
124280304Sjkim                              const unsigned char *in, size_t inl)
12568651Skris{
126280304Sjkim#  ifdef KSSL_DEBUG
127280304Sjkim    {
128109998Smarkm        int i;
129280304Sjkim        fprintf(stderr, "des_ede_cbc_cipher(ctx=%p, buflen=%d)\n", ctx,
130280304Sjkim                ctx->buf_len);
131280304Sjkim        fprintf(stderr, "\t iv= ");
132280304Sjkim        for (i = 0; i < 8; i++)
133280304Sjkim            fprintf(stderr, "%02X", ctx->iv[i]);
134280304Sjkim        fprintf(stderr, "\n");
135280304Sjkim    }
136280304Sjkim#  endif                        /* KSSL_DEBUG */
137280304Sjkim    while (inl >= EVP_MAXCHUNK) {
138280304Sjkim        DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK,
139280304Sjkim                             &data(ctx)->ks1, &data(ctx)->ks2,
140280304Sjkim                             &data(ctx)->ks3, (DES_cblock *)ctx->iv,
141280304Sjkim                             ctx->encrypt);
142280304Sjkim        inl -= EVP_MAXCHUNK;
143280304Sjkim        in += EVP_MAXCHUNK;
144280304Sjkim        out += EVP_MAXCHUNK;
145280304Sjkim    }
146280304Sjkim    if (inl)
147280304Sjkim        DES_ede3_cbc_encrypt(in, out, (long)inl,
148280304Sjkim                             &data(ctx)->ks1, &data(ctx)->ks2,
149280304Sjkim                             &data(ctx)->ks3, (DES_cblock *)ctx->iv,
150280304Sjkim                             ctx->encrypt);
151280304Sjkim    return 1;
15268651Skris}
15368651Skris
154142425Snectarstatic int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
155280304Sjkim                                const unsigned char *in, size_t inl)
15668651Skris{
157280304Sjkim    while (inl >= EVP_MAXCHUNK) {
158280304Sjkim        DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK,
159280304Sjkim                               &data(ctx)->ks1, &data(ctx)->ks2,
160280304Sjkim                               &data(ctx)->ks3, (DES_cblock *)ctx->iv,
161280304Sjkim                               &ctx->num, ctx->encrypt);
162280304Sjkim        inl -= EVP_MAXCHUNK;
163280304Sjkim        in += EVP_MAXCHUNK;
164280304Sjkim        out += EVP_MAXCHUNK;
165280304Sjkim    }
166280304Sjkim    if (inl)
167280304Sjkim        DES_ede3_cfb64_encrypt(in, out, (long)inl,
168280304Sjkim                               &data(ctx)->ks1, &data(ctx)->ks2,
169280304Sjkim                               &data(ctx)->ks3, (DES_cblock *)ctx->iv,
170280304Sjkim                               &ctx->num, ctx->encrypt);
171280304Sjkim    return 1;
17268651Skris}
17368651Skris
174280304Sjkim/*
175280304Sjkim * Although we have a CFB-r implementation for 3-DES, it doesn't pack the
176280304Sjkim * right way, so wrap it here
177280304Sjkim */
178142425Snectarstatic int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
179280304Sjkim                                const unsigned char *in, size_t inl)
180280304Sjkim{
181238405Sjkim    size_t n;
182280304Sjkim    unsigned char c[1], d[1];
183142425Snectar
184280304Sjkim    for (n = 0; n < inl; ++n) {
185280304Sjkim        c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
186280304Sjkim        DES_ede3_cfb_encrypt(c, d, 1, 1,
187280304Sjkim                             &data(ctx)->ks1, &data(ctx)->ks2,
188280304Sjkim                             &data(ctx)->ks3, (DES_cblock *)ctx->iv,
189280304Sjkim                             ctx->encrypt);
190280304Sjkim        out[n / 8] = (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8)))
191280304Sjkim            | ((d[0] & 0x80) >> (unsigned int)(n % 8));
192280304Sjkim    }
193142425Snectar
194142425Snectar    return 1;
195280304Sjkim}
196142425Snectar
197142425Snectarstatic int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
198280304Sjkim                                const unsigned char *in, size_t inl)
199280304Sjkim{
200280304Sjkim    while (inl >= EVP_MAXCHUNK) {
201280304Sjkim        DES_ede3_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK,
202280304Sjkim                             &data(ctx)->ks1, &data(ctx)->ks2,
203280304Sjkim                             &data(ctx)->ks3, (DES_cblock *)ctx->iv,
204280304Sjkim                             ctx->encrypt);
205280304Sjkim        inl -= EVP_MAXCHUNK;
206280304Sjkim        in += EVP_MAXCHUNK;
207280304Sjkim        out += EVP_MAXCHUNK;
208280304Sjkim    }
209238405Sjkim    if (inl)
210280304Sjkim        DES_ede3_cfb_encrypt(in, out, 8, (long)inl,
211280304Sjkim                             &data(ctx)->ks1, &data(ctx)->ks2,
212280304Sjkim                             &data(ctx)->ks3, (DES_cblock *)ctx->iv,
213280304Sjkim                             ctx->encrypt);
214142425Snectar    return 1;
215280304Sjkim}
216142425Snectar
217109998SmarkmBLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64,
218280304Sjkim                  EVP_CIPH_RAND_KEY, des_ede_init_key, NULL,
219280304Sjkim                  EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des3_ctrl)
220280304Sjkim#  define des_ede3_cfb64_cipher des_ede_cfb64_cipher
221280304Sjkim#  define des_ede3_ofb_cipher des_ede_ofb_cipher
222280304Sjkim#  define des_ede3_cbc_cipher des_ede_cbc_cipher
223280304Sjkim#  define des_ede3_ecb_cipher des_ede_ecb_cipher
224280304Sjkim    BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64,
225280304Sjkim                  EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL,
226280304Sjkim                  EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des3_ctrl)
22768651Skris
228280304Sjkim    BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 1,
229280304Sjkim                     EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL,
230280304Sjkim                     EVP_CIPHER_set_asn1_iv,
231280304Sjkim                     EVP_CIPHER_get_asn1_iv, des3_ctrl)
23268651Skris
233280304Sjkim    BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 8,
234280304Sjkim                     EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL,
235280304Sjkim                     EVP_CIPHER_set_asn1_iv,
236280304Sjkim                     EVP_CIPHER_get_asn1_iv, des3_ctrl)
23768651Skris
23868651Skrisstatic int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
239280304Sjkim                            const unsigned char *iv, int enc)
240280304Sjkim{
241280304Sjkim    DES_cblock *deskey = (DES_cblock *)key;
242280304Sjkim#  ifdef EVP_CHECK_DES_KEY
243280304Sjkim    if (DES_set_key_checked(&deskey[0], &data(ctx)->ks1)
244291721Sjkim        || DES_set_key_checked(&deskey[1], &data(ctx)->ks2))
245280304Sjkim        return 0;
246280304Sjkim#  else
247280304Sjkim    DES_set_key_unchecked(&deskey[0], &data(ctx)->ks1);
248280304Sjkim    DES_set_key_unchecked(&deskey[1], &data(ctx)->ks2);
249280304Sjkim#  endif
250280304Sjkim    memcpy(&data(ctx)->ks3, &data(ctx)->ks1, sizeof(data(ctx)->ks1));
251280304Sjkim    return 1;
252280304Sjkim}
25368651Skris
25468651Skrisstatic int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
255280304Sjkim                             const unsigned char *iv, int enc)
256280304Sjkim{
257280304Sjkim    DES_cblock *deskey = (DES_cblock *)key;
258280304Sjkim#  ifdef KSSL_DEBUG
259280304Sjkim    {
260109998Smarkm        int i;
261280304Sjkim        fprintf(stderr, "des_ede3_init_key(ctx=%p)\n", ctx);
262280304Sjkim        fprintf(stderr, "\tKEY= ");
263280304Sjkim        for (i = 0; i < 24; i++)
264280304Sjkim            fprintf(stderr, "%02X", key[i]);
265280304Sjkim        fprintf(stderr, "\n");
266280304Sjkim        if (iv) {
267280304Sjkim            fprintf(stderr, "\t IV= ");
268280304Sjkim            for (i = 0; i < 8; i++)
269280304Sjkim                fprintf(stderr, "%02X", iv[i]);
270280304Sjkim            fprintf(stderr, "\n");
271280304Sjkim        }
272280304Sjkim    }
273280304Sjkim#  endif                        /* KSSL_DEBUG */
27468651Skris
275280304Sjkim#  ifdef EVP_CHECK_DES_KEY
276280304Sjkim    if (DES_set_key_checked(&deskey[0], &data(ctx)->ks1)
277280304Sjkim        || DES_set_key_checked(&deskey[1], &data(ctx)->ks2)
278280304Sjkim        || DES_set_key_checked(&deskey[2], &data(ctx)->ks3))
279280304Sjkim        return 0;
280280304Sjkim#  else
281280304Sjkim    DES_set_key_unchecked(&deskey[0], &data(ctx)->ks1);
282280304Sjkim    DES_set_key_unchecked(&deskey[1], &data(ctx)->ks2);
283280304Sjkim    DES_set_key_unchecked(&deskey[2], &data(ctx)->ks3);
284280304Sjkim#  endif
285280304Sjkim    return 1;
286280304Sjkim}
28768651Skris
288160814Ssimonstatic int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
289280304Sjkim{
290160814Ssimon
291280304Sjkim    DES_cblock *deskey = ptr;
292160814Ssimon
293280304Sjkim    switch (type) {
294280304Sjkim    case EVP_CTRL_RAND_KEY:
295280304Sjkim        if (RAND_bytes(ptr, c->key_len) <= 0)
296280304Sjkim            return 0;
297280304Sjkim        DES_set_odd_parity(deskey);
298280304Sjkim        if (c->key_len >= 16)
299280304Sjkim            DES_set_odd_parity(deskey + 1);
300280304Sjkim        if (c->key_len >= 24)
301280304Sjkim            DES_set_odd_parity(deskey + 2);
302280304Sjkim        return 1;
303160814Ssimon
304280304Sjkim    default:
305280304Sjkim        return -1;
306280304Sjkim    }
307280304Sjkim}
308160814Ssimon
309109998Smarkmconst EVP_CIPHER *EVP_des_ede(void)
31068651Skris{
311280304Sjkim    return &des_ede_ecb;
31268651Skris}
31368651Skris
314109998Smarkmconst EVP_CIPHER *EVP_des_ede3(void)
31568651Skris{
316280304Sjkim    return &des_ede3_ecb;
31768651Skris}
318280304Sjkim# endif
31968651Skris#endif
320