Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

des.cpp
Go to the documentation of this file.
1 /*
2 * DES
3 * (C) 1999-2008 Jack Lloyd
4 *
5 * Based on a public domain implemenation by Phil Karn (who in turn
6 * credited Richard Outerbridge and Jim Gillogly)
7 *
8 * Botan is released under the Simplified BSD License (see license.txt)
9 */
10
11 #include <botan/des.h>
12 #include <botan/loadstor.h>
13
14 namespace Botan {
15
16 namespace {
17
18 /*
19 * DES Key Schedule
20 */
21 void des_key_schedule(uint32_t round_key[32], const uint8_t key[8])
22 {
23 static const uint8_t ROT[16] = { 1, 1, 2, 2, 2, 2, 2, 2,
24 1, 2, 2, 2, 2, 2, 2, 1 };
25
26 uint32_t C = ((key[7] & 0x80) << 20) | ((key[6] & 0x80) << 19) |
27 ((key[5] & 0x80) << 18) | ((key[4] & 0x80) << 17) |
28 ((key[3] & 0x80) << 16) | ((key[2] & 0x80) << 15) |
29 ((key[1] & 0x80) << 14) | ((key[0] & 0x80) << 13) |
30 ((key[7] & 0x40) << 13) | ((key[6] & 0x40) << 12) |
31 ((key[5] & 0x40) << 11) | ((key[4] & 0x40) << 10) |
32 ((key[3] & 0x40) << 9) | ((key[2] & 0x40) << 8) |
33 ((key[1] & 0x40) << 7) | ((key[0] & 0x40) << 6) |
34 ((key[7] & 0x20) << 6) | ((key[6] & 0x20) << 5) |
35 ((key[5] & 0x20) << 4) | ((key[4] & 0x20) << 3) |
36 ((key[3] & 0x20) << 2) | ((key[2] & 0x20) << 1) |
37 ((key[1] & 0x20) ) | ((key[0] & 0x20) >> 1) |
38 ((key[7] & 0x10) >> 1) | ((key[6] & 0x10) >> 2) |
39 ((key[5] & 0x10) >> 3) | ((key[4] & 0x10) >> 4);
40 uint32_t D = ((key[7] & 0x02) << 26) | ((key[6] & 0x02) << 25) |
41 ((key[5] & 0x02) << 24) | ((key[4] & 0x02) << 23) |
42 ((key[3] & 0x02) << 22) | ((key[2] & 0x02) << 21) |
43 ((key[1] & 0x02) << 20) | ((key[0] & 0x02) << 19) |
44 ((key[7] & 0x04) << 17) | ((key[6] & 0x04) << 16) |
45 ((key[5] & 0x04) << 15) | ((key[4] & 0x04) << 14) |
46 ((key[3] & 0x04) << 13) | ((key[2] & 0x04) << 12) |
47 ((key[1] & 0x04) << 11) | ((key[0] & 0x04) << 10) |
48 ((key[7] & 0x08) << 8) | ((key[6] & 0x08) << 7) |
49 ((key[5] & 0x08) << 6) | ((key[4] & 0x08) << 5) |
50 ((key[3] & 0x08) << 4) | ((key[2] & 0x08) << 3) |
51 ((key[1] & 0x08) << 2) | ((key[0] & 0x08) << 1) |
52 ((key[3] & 0x10) >> 1) | ((key[2] & 0x10) >> 2) |
53 ((key[1] & 0x10) >> 3) | ((key[0] & 0x10) >> 4);
54
55 for(size_t i = 0; i != 16; ++i)
56 {
57 C = ((C << ROT[i]) | (C >> (28-ROT[i]))) & 0x0FFFFFFF;
58 D = ((D << ROT[i]) | (D >> (28-ROT[i]))) & 0x0FFFFFFF;
59 round_key[2*i ] = ((C & 0x00000010) << 22) | ((C & 0x00000800) << 17) |
60 ((C & 0x00000020) << 16) | ((C & 0x00004004) << 15) |
61 ((C & 0x00000200) << 11) | ((C & 0x00020000) << 10) |
62 ((C & 0x01000000) >> 6) | ((C & 0x00100000) >> 4) |
63 ((C & 0x00010000) << 3) | ((C & 0x08000000) >> 2) |
64 ((C & 0x00800000) << 1) | ((D & 0x00000010) << 8) |
65 ((D & 0x00000002) << 7) | ((D & 0x00000001) << 2) |
66 ((D & 0x00000200) ) | ((D & 0x00008000) >> 2) |
67 ((D & 0x00000088) >> 3) | ((D & 0x00001000) >> 7) |
68 ((D & 0x00080000) >> 9) | ((D & 0x02020000) >> 14) |
69 ((D & 0x00400000) >> 21);
70 round_key[2*i+1] = ((C & 0x00000001) << 28) | ((C & 0x00000082) << 18) |
71 ((C & 0x00002000) << 14) | ((C & 0x00000100) << 10) |
72 ((C & 0x00001000) << 9) | ((C & 0x00040000) << 6) |
73 ((C & 0x02400000) << 4) | ((C & 0x00008000) << 2) |
74 ((C & 0x00200000) >> 1) | ((C & 0x04000000) >> 10) |
75 ((D & 0x00000020) << 6) | ((D & 0x00000100) ) |
76 ((D & 0x00000800) >> 1) | ((D & 0x00000040) >> 3) |
77 ((D & 0x00010000) >> 4) | ((D & 0x00000400) >> 5) |
78 ((D & 0x00004000) >> 10) | ((D & 0x04000000) >> 13) |
79 ((D & 0x00800000) >> 14) | ((D & 0x00100000) >> 18) |
80 ((D & 0x01000000) >> 24) | ((D & 0x08000000) >> 26);
81 }
82 }
83
84 /*
85 * DES Encryption
86 */
87 void des_encrypt(uint32_t& L, uint32_t& R,
88 const uint32_t round_key[32])
89 {
90 for(size_t i = 0; i != 16; i += 2)
91 {
92 uint32_t T0, T1;
93
94 T0 = rotate_right(R, 4) ^ round_key[2*i];
95 T1 = R ^ round_key[2*i + 1];
96
97 L ^= DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^
98 DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^
99 DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^
100 DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)];
101
102 T0 = rotate_right(L, 4) ^ round_key[2*i + 2];
103 T1 = L ^ round_key[2*i + 3];
104
105 R ^= DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^
106 DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^
107 DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^
108 DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)];
109 }
110 }
111
112 /*
113 * DES Decryption
114 */
115 void des_decrypt(uint32_t& L, uint32_t& R,
116 const uint32_t round_key[32])
117 {
118 for(size_t i = 16; i != 0; i -= 2)
119 {
120 uint32_t T0, T1;
121
122 T0 = rotate_right(R, 4) ^ round_key[2*i - 2];
123 T1 = R ^ round_key[2*i - 1];
124
125 L ^= DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^
126 DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^
127 DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^
128 DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)];
129
130 T0 = rotate_right(L, 4) ^ round_key[2*i - 4];
131 T1 = L ^ round_key[2*i - 3];
132
133 R ^= DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^
134 DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^
135 DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^
136 DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)];
137 }
138 }
139
140 }
141
142 /*
143 * DES Encryption
144 */
145 void DES::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
146 {
147 for(size_t i = 0; i < blocks; ++i)
148 {
149 uint64_t T = (DES_IPTAB1[in[8*i+0]] ) | (DES_IPTAB1[in[8*i+1]] << 1) |
150 (DES_IPTAB1[in[8*i+2]] << 2) | (DES_IPTAB1[in[8*i+3]] << 3) |
151 (DES_IPTAB1[in[8*i+4]] << 4) | (DES_IPTAB1[in[8*i+5]] << 5) |
152 (DES_IPTAB1[in[8*i+6]] << 6) | (DES_IPTAB2[in[8*i+7]] );
153
154 uint32_t L = static_cast<uint32_t>(T >> 32);
155 uint32_t R = static_cast<uint32_t>(T);
156
157 des_encrypt(L, R, m_round_key.data());
158
159 T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
160 (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
161 (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
162 (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
163 T = rotate_left(T, 32);
164
165 store_be(T, out + 8*i);
166 }
167 }
168
169 /*
170 * DES Decryption
171 */
172 void DES::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
173 {
174 for(size_t i = 0; i < blocks; ++i)
175 {
176 uint64_t T = (DES_IPTAB1[in[BLOCK_SIZE*i+0]] ) | (DES_IPTAB1[in[BLOCK_SIZE*i+1]] << 1) |
177 (DES_IPTAB1[in[BLOCK_SIZE*i+2]] << 2) | (DES_IPTAB1[in[BLOCK_SIZE*i+3]] << 3) |
178 (DES_IPTAB1[in[BLOCK_SIZE*i+4]] << 4) | (DES_IPTAB1[in[BLOCK_SIZE*i+5]] << 5) |
179 (DES_IPTAB1[in[BLOCK_SIZE*i+6]] << 6) | (DES_IPTAB2[in[BLOCK_SIZE*i+7]] );
180
181 uint32_t L = static_cast<uint32_t>(T >> 32);
182 uint32_t R = static_cast<uint32_t>(T);
183
184 des_decrypt(L, R, m_round_key.data());
185
186 T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
187 (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
188 (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
189 (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
190
191 T = rotate_left(T, 32);
192
193 store_be(T, out + BLOCK_SIZE*i);
194 }
195 }
196
197 /*
198 * DES Key Schedule
199 */
200 void DES::key_schedule(const uint8_t key[], size_t)
201 {
202 m_round_key.resize(32);
203 des_key_schedule(m_round_key.data(), key);
204 }
205
206 void DES::clear()
207 {
208 zap(m_round_key);
209 }
210
211 /*
212 * TripleDES Encryption
213 */
214 void TripleDES::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
215 {
216 for(size_t i = 0; i != blocks; ++i)
217 {
218 uint64_t T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
219 (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
220 (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
221 (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
222
223 uint32_t L = static_cast<uint32_t>(T >> 32);
224 uint32_t R = static_cast<uint32_t>(T);
225
226 des_encrypt(L, R, &m_round_key[0]);
227 des_decrypt(R, L, &m_round_key[32]);
228 des_encrypt(L, R, &m_round_key[64]);
229
230 T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
231 (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
232 (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
233 (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
234
235 T = rotate_left(T, 32);
236
237 store_be(T, out);
238
239 in += BLOCK_SIZE;
240 out += BLOCK_SIZE;
241 }
242 }
243
244 /*
245 * TripleDES Decryption
246 */
247 void TripleDES::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
248 {
249 for(size_t i = 0; i != blocks; ++i)
250 {
251 uint64_t T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
252 (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
253 (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
254 (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
255
256 uint32_t L = static_cast<uint32_t>(T >> 32);
257 uint32_t R = static_cast<uint32_t>(T);
258
259 des_decrypt(L, R, &m_round_key[64]);
260 des_encrypt(R, L, &m_round_key[32]);
261 des_decrypt(L, R, &m_round_key[0]);
262
263 T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
264 (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
265 (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
266 (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
267
268 T = rotate_left(T, 32);
269
270 store_be(T, out);
271
272 in += BLOCK_SIZE;
273 out += BLOCK_SIZE;
274 }
275 }
276
277 /*
278 * TripleDES Key Schedule
279 */
280 void TripleDES::key_schedule(const uint8_t key[], size_t length)
281 {
282 m_round_key.resize(3*32);
283 des_key_schedule(&m_round_key[0], key);
284 des_key_schedule(&m_round_key[32], key + 8);
285
286 if(length == 24)
287 des_key_schedule(&m_round_key[64], key + 16);
288 else
289 copy_mem(&m_round_key[64], &m_round_key[0], 32);
290 }
291
292 void TripleDES::clear()
293 {
294 zap(m_round_key);
295 }
296
297 }
Botan::DES::decrypt_n
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition: des.cpp:172
Botan::DES_IPTAB2
const uint64_t DES_IPTAB2[256]
Definition: des_tab.cpp:438
Botan::DES_SPBOX6
const uint32_t DES_SPBOX6[256]
Definition: des_tab.cpp:237
Botan::DES_SPBOX7
const uint32_t DES_SPBOX7[256]
Definition: des_tab.cpp:282
Botan::Block_Cipher_Fixed_Params< 8, 8 >::BLOCK_SIZE
Definition: block_cipher.h:186
Botan::zap
void zap(std::vector< T, Alloc > &vec)
Definition: secmem.h:221
Botan::TripleDES::decrypt_n
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition: des.cpp:247
Botan::store_be
void store_be(uint16_t in, uint8_t out[2])
Definition: loadstor.h:441
Botan::DES_IPTAB1
const uint64_t DES_IPTAB1[256]
Definition: des_tab.cpp:372
Botan::DES_SPBOX4
const uint32_t DES_SPBOX4[256]
Definition: des_tab.cpp:147
Botan::rotate_left
T rotate_left(T input, size_t rot)
Definition: rotate.h:21
Botan::TripleDES::encrypt_n
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition: des.cpp:214
Botan::DES::encrypt_n
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition: des.cpp:145
Botan::DES_SPBOX3
const uint32_t DES_SPBOX3[256]
Definition: des_tab.cpp:102
Botan::DES_SPBOX8
const uint32_t DES_SPBOX8[256]
Definition: des_tab.cpp:327
Botan::rotate_right
T rotate_right(T input, size_t rot)
Definition: rotate.h:32
Botan::DES_SPBOX1
const uint32_t DES_SPBOX1[256]
Definition: des_tab.cpp:12
Botan::copy_mem
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:68
Botan
Definition: alg_id.cpp:13
Botan::DES_SPBOX5
const uint32_t DES_SPBOX5[256]
Definition: des_tab.cpp:192
Botan::DES_SPBOX2
const uint32_t DES_SPBOX2[256]
Definition: des_tab.cpp:57
Botan::get_byte
uint8_t get_byte(size_t byte_num, T input)
Definition: loadstor.h:47
Botan::DES_FPTAB1
const uint64_t DES_FPTAB1[256]
Definition: des_tab.cpp:504
Botan::DES::clear
void clear() override
Definition: des.cpp:206
Botan::TripleDES::clear
void clear() override
Definition: des.cpp:292
Botan::DES_FPTAB2
const uint64_t DES_FPTAB2[256]
Definition: des_tab.cpp:570