168651Skris/* crypto/evp/e_des.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
6868651Skrisstatic int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
69280304Sjkim                        const unsigned char *iv, int enc);
70160814Ssimonstatic int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
7168651Skris
72280304Sjkim/*
73280304Sjkim * Because of various casts and different names can't use
74280304Sjkim * IMPLEMENT_BLOCK_CIPHER
75280304Sjkim */
7668651Skris
7768651Skrisstatic int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
78280304Sjkim                          const unsigned char *in, size_t inl)
7968651Skris{
80280304Sjkim    BLOCK_CIPHER_ecb_loop()
81280304Sjkim        DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i),
82280304Sjkim                        ctx->cipher_data, ctx->encrypt);
83280304Sjkim    return 1;
8468651Skris}
8568651Skris
8668651Skrisstatic int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
87280304Sjkim                          const unsigned char *in, size_t inl)
8868651Skris{
89280304Sjkim    while (inl >= EVP_MAXCHUNK) {
90280304Sjkim        DES_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data,
91280304Sjkim                          (DES_cblock *)ctx->iv, &ctx->num);
92280304Sjkim        inl -= EVP_MAXCHUNK;
93280304Sjkim        in += EVP_MAXCHUNK;
94280304Sjkim        out += EVP_MAXCHUNK;
95280304Sjkim    }
96280304Sjkim    if (inl)
97280304Sjkim        DES_ofb64_encrypt(in, out, (long)inl, ctx->cipher_data,
98280304Sjkim                          (DES_cblock *)ctx->iv, &ctx->num);
99280304Sjkim    return 1;
10068651Skris}
10168651Skris
10268651Skrisstatic int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
103280304Sjkim                          const unsigned char *in, size_t inl)
10468651Skris{
105280304Sjkim    while (inl >= EVP_MAXCHUNK) {
106280304Sjkim        DES_ncbc_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data,
107280304Sjkim                         (DES_cblock *)ctx->iv, ctx->encrypt);
108280304Sjkim        inl -= EVP_MAXCHUNK;
109280304Sjkim        in += EVP_MAXCHUNK;
110280304Sjkim        out += EVP_MAXCHUNK;
111280304Sjkim    }
112280304Sjkim    if (inl)
113280304Sjkim        DES_ncbc_encrypt(in, out, (long)inl, ctx->cipher_data,
114280304Sjkim                         (DES_cblock *)ctx->iv, ctx->encrypt);
115280304Sjkim    return 1;
11668651Skris}
11768651Skris
118142425Snectarstatic int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
119280304Sjkim                            const unsigned char *in, size_t inl)
12068651Skris{
121280304Sjkim    while (inl >= EVP_MAXCHUNK) {
122280304Sjkim        DES_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data,
123280304Sjkim                          (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
124280304Sjkim        inl -= EVP_MAXCHUNK;
125280304Sjkim        in += EVP_MAXCHUNK;
126280304Sjkim        out += EVP_MAXCHUNK;
127280304Sjkim    }
128280304Sjkim    if (inl)
129280304Sjkim        DES_cfb64_encrypt(in, out, (long)inl, ctx->cipher_data,
130280304Sjkim                          (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
131280304Sjkim    return 1;
13268651Skris}
13368651Skris
134280304Sjkim/*
135280304Sjkim * Although we have a CFB-r implementation for DES, it doesn't pack the right
136280304Sjkim * way, so wrap it here
137280304Sjkim */
138142425Snectarstatic int des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
139280304Sjkim                           const unsigned char *in, size_t inl)
140280304Sjkim{
141280304Sjkim    size_t n, chunk = EVP_MAXCHUNK / 8;
142280304Sjkim    unsigned char c[1], d[1];
143142425Snectar
144280304Sjkim    if (inl < chunk)
145280304Sjkim        chunk = inl;
146238405Sjkim
147280304Sjkim    while (inl && inl >= chunk) {
148280304Sjkim        for (n = 0; n < chunk * 8; ++n) {
149280304Sjkim            c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
150280304Sjkim            DES_cfb_encrypt(c, d, 1, 1, ctx->cipher_data,
151280304Sjkim                            (DES_cblock *)ctx->iv, ctx->encrypt);
152280304Sjkim            out[n / 8] =
153280304Sjkim                (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) |
154280304Sjkim                ((d[0] & 0x80) >> (unsigned int)(n % 8));
155280304Sjkim        }
156280304Sjkim        inl -= chunk;
157280304Sjkim        in += chunk;
158280304Sjkim        out += chunk;
159280304Sjkim        if (inl < chunk)
160280304Sjkim            chunk = inl;
161280304Sjkim    }
162238405Sjkim
163142425Snectar    return 1;
164280304Sjkim}
165142425Snectar
166142425Snectarstatic int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
167280304Sjkim                           const unsigned char *in, size_t inl)
168280304Sjkim{
169280304Sjkim    while (inl >= EVP_MAXCHUNK) {
170280304Sjkim        DES_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK, ctx->cipher_data,
171280304Sjkim                        (DES_cblock *)ctx->iv, ctx->encrypt);
172280304Sjkim        inl -= EVP_MAXCHUNK;
173280304Sjkim        in += EVP_MAXCHUNK;
174280304Sjkim        out += EVP_MAXCHUNK;
175280304Sjkim    }
176238405Sjkim    if (inl)
177280304Sjkim        DES_cfb_encrypt(in, out, 8, (long)inl, ctx->cipher_data,
178280304Sjkim                        (DES_cblock *)ctx->iv, ctx->encrypt);
179142425Snectar    return 1;
180280304Sjkim}
181142425Snectar
182109998SmarkmBLOCK_CIPHER_defs(des, DES_key_schedule, NID_des, 8, 8, 8, 64,
183280304Sjkim                  EVP_CIPH_RAND_KEY, des_init_key, NULL,
184280304Sjkim                  EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl)
18568651Skris
18668651Skris
187280304SjkimBLOCK_CIPHER_def_cfb(des, DES_key_schedule, NID_des, 8, 8, 1,
188280304Sjkim                 EVP_CIPH_RAND_KEY, des_init_key, NULL,
189280304Sjkim                 EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl)
190142425Snectar
191280304SjkimBLOCK_CIPHER_def_cfb(des, DES_key_schedule, NID_des, 8, 8, 8,
192280304Sjkim                     EVP_CIPH_RAND_KEY, des_init_key, NULL,
193280304Sjkim                     EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl)
194280304Sjkim
19568651Skrisstatic int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
196280304Sjkim                        const unsigned char *iv, int enc)
197280304Sjkim{
198280304Sjkim    DES_cblock *deskey = (DES_cblock *)key;
199280304Sjkim# ifdef EVP_CHECK_DES_KEY
200280304Sjkim    if (DES_set_key_checked(deskey, ctx->cipher_data) != 0)
201280304Sjkim        return 0;
202280304Sjkim# else
203280304Sjkim    DES_set_key_unchecked(deskey, ctx->cipher_data);
204280304Sjkim# endif
205280304Sjkim    return 1;
206280304Sjkim}
20768651Skris
208160814Ssimonstatic int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
209280304Sjkim{
210160814Ssimon
211280304Sjkim    switch (type) {
212280304Sjkim    case EVP_CTRL_RAND_KEY:
213280304Sjkim        if (RAND_bytes(ptr, 8) <= 0)
214280304Sjkim            return 0;
215280304Sjkim        DES_set_odd_parity((DES_cblock *)ptr);
216280304Sjkim        return 1;
217160814Ssimon
218280304Sjkim    default:
219280304Sjkim        return -1;
220280304Sjkim    }
221280304Sjkim}
222280304Sjkim
22368651Skris#endif
224