3b4b714e38e8d84e4dc8555e29948e5854152c9c
[openssl.git] / crypto / evp / e_des.c
1 /*
2  * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <stdio.h>
11 #include "internal/cryptlib.h"
12 #ifndef OPENSSL_NO_DES
13 # include <openssl/evp.h>
14 # include <openssl/objects.h>
15 # include "internal/evp_int.h"
16 # include <openssl/des.h>
17 # include <openssl/rand.h>
18 # include <openssl/rand_drbg.h>
19 # include "evp_locl.h"
20
21 typedef struct {
22     union {
23         double align;
24         DES_key_schedule ks;
25     } ks;
26     union {
27         void (*cbc) (const void *, void *, size_t,
28                      const DES_key_schedule *, unsigned char *);
29     } stream;
30 } EVP_DES_KEY;
31
32 # if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
33 /* ----------^^^ this is not a typo, just a way to detect that
34  * assembler support was in general requested... */
35 #  include "sparc_arch.h"
36
37 extern unsigned int OPENSSL_sparcv9cap_P[];
38
39 #  define SPARC_DES_CAPABLE       (OPENSSL_sparcv9cap_P[1] & CFR_DES)
40
41 void des_t4_key_expand(const void *key, DES_key_schedule *ks);
42 void des_t4_cbc_encrypt(const void *inp, void *out, size_t len,
43                         const DES_key_schedule *ks, unsigned char iv[8]);
44 void des_t4_cbc_decrypt(const void *inp, void *out, size_t len,
45                         const DES_key_schedule *ks, unsigned char iv[8]);
46 # endif
47
48 static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
49                         const unsigned char *iv, int enc);
50 static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
51
52 /*
53  * Because of various casts and different names can't use
54  * IMPLEMENT_BLOCK_CIPHER
55  */
56
57 static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
58                           const unsigned char *in, size_t inl)
59 {
60     BLOCK_CIPHER_ecb_loop()
61         DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i),
62                         EVP_CIPHER_CTX_get_cipher_data(ctx),
63                         EVP_CIPHER_CTX_encrypting(ctx));
64     return 1;
65 }
66
67 static int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
68                           const unsigned char *in, size_t inl)
69 {
70     while (inl >= EVP_MAXCHUNK) {
71         int num = EVP_CIPHER_CTX_num(ctx);
72         DES_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK,
73                           EVP_CIPHER_CTX_get_cipher_data(ctx),
74                           (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num);
75         EVP_CIPHER_CTX_set_num(ctx, num);
76         inl -= EVP_MAXCHUNK;
77         in += EVP_MAXCHUNK;
78         out += EVP_MAXCHUNK;
79     }
80     if (inl) {
81         int num = EVP_CIPHER_CTX_num(ctx);
82         DES_ofb64_encrypt(in, out, (long)inl,
83                           EVP_CIPHER_CTX_get_cipher_data(ctx),
84                           (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num);
85         EVP_CIPHER_CTX_set_num(ctx, num);
86     }
87     return 1;
88 }
89
90 static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
91                           const unsigned char *in, size_t inl)
92 {
93     EVP_DES_KEY *dat = (EVP_DES_KEY *) EVP_CIPHER_CTX_get_cipher_data(ctx);
94
95     if (dat->stream.cbc != NULL) {
96         (*dat->stream.cbc) (in, out, inl, &dat->ks.ks,
97                             EVP_CIPHER_CTX_iv_noconst(ctx));
98         return 1;
99     }
100     while (inl >= EVP_MAXCHUNK) {
101         DES_ncbc_encrypt(in, out, (long)EVP_MAXCHUNK,
102                          EVP_CIPHER_CTX_get_cipher_data(ctx),
103                          (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
104                          EVP_CIPHER_CTX_encrypting(ctx));
105         inl -= EVP_MAXCHUNK;
106         in += EVP_MAXCHUNK;
107         out += EVP_MAXCHUNK;
108     }
109     if (inl)
110         DES_ncbc_encrypt(in, out, (long)inl,
111                          EVP_CIPHER_CTX_get_cipher_data(ctx),
112                          (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
113                          EVP_CIPHER_CTX_encrypting(ctx));
114     return 1;
115 }
116
117 static int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
118                             const unsigned char *in, size_t inl)
119 {
120     while (inl >= EVP_MAXCHUNK) {
121         int num = EVP_CIPHER_CTX_num(ctx);
122         DES_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK,
123                           EVP_CIPHER_CTX_get_cipher_data(ctx),
124                           (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num,
125                           EVP_CIPHER_CTX_encrypting(ctx));
126         EVP_CIPHER_CTX_set_num(ctx, num);
127         inl -= EVP_MAXCHUNK;
128         in += EVP_MAXCHUNK;
129         out += EVP_MAXCHUNK;
130     }
131     if (inl) {
132         int num = EVP_CIPHER_CTX_num(ctx);
133         DES_cfb64_encrypt(in, out, (long)inl,
134                           EVP_CIPHER_CTX_get_cipher_data(ctx),
135                           (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num,
136                           EVP_CIPHER_CTX_encrypting(ctx));
137         EVP_CIPHER_CTX_set_num(ctx, num);
138     }
139     return 1;
140 }
141
142 /*
143  * Although we have a CFB-r implementation for DES, it doesn't pack the right
144  * way, so wrap it here
145  */
146 static int des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
147                            const unsigned char *in, size_t inl)
148 {
149     size_t n, chunk = EVP_MAXCHUNK / 8;
150     unsigned char c[1], d[1];
151
152     if (inl < chunk)
153         chunk = inl;
154
155     while (inl && inl >= chunk) {
156         for (n = 0; n < chunk * 8; ++n) {
157             c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
158             DES_cfb_encrypt(c, d, 1, 1, EVP_CIPHER_CTX_get_cipher_data(ctx),
159                             (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
160                             EVP_CIPHER_CTX_encrypting(ctx));
161             out[n / 8] =
162                 (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) |
163                 ((d[0] & 0x80) >> (unsigned int)(n % 8));
164         }
165         inl -= chunk;
166         in += chunk;
167         out += chunk;
168         if (inl < chunk)
169             chunk = inl;
170     }
171
172     return 1;
173 }
174
175 static int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
176                            const unsigned char *in, size_t inl)
177 {
178     while (inl >= EVP_MAXCHUNK) {
179         DES_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK,
180                         EVP_CIPHER_CTX_get_cipher_data(ctx),
181                         (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
182                         EVP_CIPHER_CTX_encrypting(ctx));
183         inl -= EVP_MAXCHUNK;
184         in += EVP_MAXCHUNK;
185         out += EVP_MAXCHUNK;
186     }
187     if (inl)
188         DES_cfb_encrypt(in, out, 8, (long)inl,
189                         EVP_CIPHER_CTX_get_cipher_data(ctx),
190                         (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
191                         EVP_CIPHER_CTX_encrypting(ctx));
192     return 1;
193 }
194
195 BLOCK_CIPHER_defs(des, EVP_DES_KEY, NID_des, 8, 8, 8, 64,
196                   EVP_CIPH_RAND_KEY, des_init_key, NULL,
197                   EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl)
198
199     BLOCK_CIPHER_def_cfb(des, EVP_DES_KEY, NID_des, 8, 8, 1,
200                      EVP_CIPH_RAND_KEY, des_init_key, NULL,
201                      EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl)
202
203     BLOCK_CIPHER_def_cfb(des, EVP_DES_KEY, NID_des, 8, 8, 8,
204                      EVP_CIPH_RAND_KEY, des_init_key, NULL,
205                      EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl)
206
207 static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
208                         const unsigned char *iv, int enc)
209 {
210     DES_cblock *deskey = (DES_cblock *)key;
211     EVP_DES_KEY *dat = (EVP_DES_KEY *) EVP_CIPHER_CTX_get_cipher_data(ctx);
212
213     dat->stream.cbc = NULL;
214 # if defined(SPARC_DES_CAPABLE)
215     if (SPARC_DES_CAPABLE) {
216         int mode = EVP_CIPHER_CTX_mode(ctx);
217
218         if (mode == EVP_CIPH_CBC_MODE) {
219             des_t4_key_expand(key, &dat->ks.ks);
220             dat->stream.cbc = enc ? des_t4_cbc_encrypt : des_t4_cbc_decrypt;
221             return 1;
222         }
223     }
224 # endif
225     DES_set_key_unchecked(deskey, EVP_CIPHER_CTX_get_cipher_data(ctx));
226     return 1;
227 }
228
229 static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
230 {
231
232     switch (type) {
233     case EVP_CTRL_RAND_KEY:
234         if (c->drbg != NULL) {
235             if (RAND_DRBG_bytes(c->drbg, ptr, 8) == 0)
236                 return 0;
237         } else if (RAND_bytes(ptr, 8) <= 0) {
238             return 0;
239         }
240         DES_set_odd_parity((DES_cblock *)ptr);
241         return 1;
242
243     default:
244         return -1;
245     }
246 }
247
248 #endif