1 // Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <string.h>
16 
17 #include <openssl/des.h>
18 
19 #include "../../crypto/des/internal.h"
20 #include "../../crypto/internal.h"
21 
22 
23 // The input and output encrypted as though 64bit cfb mode is being used. The
24 // extra state information to record how much of the 64bit block we have used
25 // is contained in *num;
DES_ede3_cfb64_encrypt(const uint8_t * in,uint8_t * out,long length,DES_key_schedule * ks1,DES_key_schedule * ks2,DES_key_schedule * ks3,DES_cblock * ivec,int * num,int enc)26 void DES_ede3_cfb64_encrypt(const uint8_t *in, uint8_t *out,
27                             long length, DES_key_schedule *ks1,
28                             DES_key_schedule *ks2, DES_key_schedule *ks3,
29                             DES_cblock *ivec, int *num, int enc) {
30   uint32_t v0, v1;
31   long l = length;
32   int n = *num;
33   uint32_t ti[2];
34   uint8_t *iv, c, cc;
35 
36   iv = ivec->bytes;
37   if (enc) {
38     while (l--) {
39       if (n == 0) {
40         c2l(iv, v0);
41         c2l(iv, v1);
42 
43         ti[0] = v0;
44         ti[1] = v1;
45         DES_encrypt3(ti, ks1, ks2, ks3);
46         v0 = ti[0];
47         v1 = ti[1];
48 
49         iv = ivec->bytes;
50         l2c(v0, iv);
51         l2c(v1, iv);
52         iv = ivec->bytes;
53       }
54       c = *(in++) ^ iv[n];
55       *(out++) = c;
56       iv[n] = c;
57       n = (n + 1) & 0x07;
58     }
59   } else {
60     while (l--) {
61       if (n == 0) {
62         c2l(iv, v0);
63         c2l(iv, v1);
64 
65         ti[0] = v0;
66         ti[1] = v1;
67         DES_encrypt3(ti, ks1, ks2, ks3);
68         v0 = ti[0];
69         v1 = ti[1];
70 
71         iv = ivec->bytes;
72         l2c(v0, iv);
73         l2c(v1, iv);
74         iv = ivec->bytes;
75       }
76       cc = *(in++);
77       c = iv[n];
78       iv[n] = cc;
79       *(out++) = c ^ cc;
80       n = (n + 1) & 0x07;
81     }
82   }
83   v0 = v1 = ti[0] = ti[1] = c = cc = 0;
84   *num = n;
85 }
86 
87 // This is compatible with the single key CFB-r for DES, even thought that's
88 // not what EVP needs.
89 
DES_ede3_cfb_encrypt(const uint8_t * in,uint8_t * out,int numbits,long length,DES_key_schedule * ks1,DES_key_schedule * ks2,DES_key_schedule * ks3,DES_cblock * ivec,int enc)90 void DES_ede3_cfb_encrypt(const uint8_t *in, uint8_t *out, int numbits,
91                           long length, DES_key_schedule *ks1,
92                           DES_key_schedule *ks2, DES_key_schedule *ks3,
93                           DES_cblock *ivec, int enc) {
94   uint32_t d0, d1, v0, v1;
95   unsigned long l = length, n = ((unsigned int)numbits + 7) / 8;
96   int num = numbits, i;
97   uint32_t ti[2];
98   uint8_t *iv;
99   uint8_t ovec[16];
100 
101   if (num > 64) {
102     return;
103   }
104 
105   iv = ivec->bytes;
106   c2l(iv, v0);
107   c2l(iv, v1);
108 
109   if (enc) {
110     while (l >= n) {
111       l -= n;
112       ti[0] = v0;
113       ti[1] = v1;
114       DES_encrypt3(ti, ks1, ks2, ks3);
115       c2ln(in, d0, d1, n);
116       in += n;
117       d0 ^= ti[0];
118       d1 ^= ti[1];
119       l2cn(d0, d1, out, n);
120       out += n;
121       // 30-08-94 - eay - changed because l>>32 and l<<32 are bad under
122       // gcc :-(
123       if (num == 32) {
124         v0 = v1;
125         v1 = d0;
126       } else if (num == 64) {
127         v0 = d0;
128         v1 = d1;
129       } else {
130         iv = &ovec[0];
131         l2c(v0, iv);
132         l2c(v1, iv);
133         l2c(d0, iv);
134         l2c(d1, iv);
135         // shift ovec left most of the bits...
136         OPENSSL_memmove(ovec, ovec + num / 8, 8 + (num % 8 ? 1 : 0));
137         // now the remaining bits
138         if (num % 8 != 0) {
139           for (i = 0; i < 8; ++i) {
140             ovec[i] <<= num % 8;
141             ovec[i] |= ovec[i + 1] >> (8 - num % 8);
142           }
143         }
144         iv = &ovec[0];
145         c2l(iv, v0);
146         c2l(iv, v1);
147       }
148     }
149   } else {
150     while (l >= n) {
151       l -= n;
152       ti[0] = v0;
153       ti[1] = v1;
154       DES_encrypt3(ti, ks1, ks2, ks3);
155       c2ln(in, d0, d1, n);
156       in += n;
157       // 30-08-94 - eay - changed because l>>32 and l<<32 are bad under
158       // gcc :-(
159       if (num == 32) {
160         v0 = v1;
161         v1 = d0;
162       } else if (num == 64) {
163         v0 = d0;
164         v1 = d1;
165       } else {
166         iv = &ovec[0];
167         l2c(v0, iv);
168         l2c(v1, iv);
169         l2c(d0, iv);
170         l2c(d1, iv);
171         // shift ovec left most of the bits...
172         OPENSSL_memmove(ovec, ovec + num / 8, 8 + (num % 8 ? 1 : 0));
173         // now the remaining bits
174         if (num % 8 != 0) {
175           for (i = 0; i < 8; ++i) {
176             ovec[i] <<= num % 8;
177             ovec[i] |= ovec[i + 1] >> (8 - num % 8);
178           }
179         }
180         iv = &ovec[0];
181         c2l(iv, v0);
182         c2l(iv, v1);
183       }
184       d0 ^= ti[0];
185       d1 ^= ti[1];
186       l2cn(d0, d1, out, n);
187       out += n;
188     }
189   }
190 
191   iv = ivec->bytes;
192   l2c(v0, iv);
193   l2c(v1, iv);
194   v0 = v1 = d0 = d1 = ti[0] = ti[1] = 0;
195 }
196