Botan  2.12.1
Crypto and TLS for C++11
des.cpp
Go to the documentation of this file.
1 /*
2 * DES
3 * (C) 1999-2008,2018 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 #include <botan/rotate.h>
14 
15 namespace Botan {
16 
17 namespace {
18 
19 /*
20 * DES Key Schedule
21 */
22 void des_key_schedule(uint32_t round_key[32], const uint8_t key[8])
23  {
24  static const uint8_t ROT[16] = { 1, 1, 2, 2, 2, 2, 2, 2,
25  1, 2, 2, 2, 2, 2, 2, 1 };
26 
27  uint32_t C = ((key[7] & 0x80) << 20) | ((key[6] & 0x80) << 19) |
28  ((key[5] & 0x80) << 18) | ((key[4] & 0x80) << 17) |
29  ((key[3] & 0x80) << 16) | ((key[2] & 0x80) << 15) |
30  ((key[1] & 0x80) << 14) | ((key[0] & 0x80) << 13) |
31  ((key[7] & 0x40) << 13) | ((key[6] & 0x40) << 12) |
32  ((key[5] & 0x40) << 11) | ((key[4] & 0x40) << 10) |
33  ((key[3] & 0x40) << 9) | ((key[2] & 0x40) << 8) |
34  ((key[1] & 0x40) << 7) | ((key[0] & 0x40) << 6) |
35  ((key[7] & 0x20) << 6) | ((key[6] & 0x20) << 5) |
36  ((key[5] & 0x20) << 4) | ((key[4] & 0x20) << 3) |
37  ((key[3] & 0x20) << 2) | ((key[2] & 0x20) << 1) |
38  ((key[1] & 0x20) ) | ((key[0] & 0x20) >> 1) |
39  ((key[7] & 0x10) >> 1) | ((key[6] & 0x10) >> 2) |
40  ((key[5] & 0x10) >> 3) | ((key[4] & 0x10) >> 4);
41  uint32_t D = ((key[7] & 0x02) << 26) | ((key[6] & 0x02) << 25) |
42  ((key[5] & 0x02) << 24) | ((key[4] & 0x02) << 23) |
43  ((key[3] & 0x02) << 22) | ((key[2] & 0x02) << 21) |
44  ((key[1] & 0x02) << 20) | ((key[0] & 0x02) << 19) |
45  ((key[7] & 0x04) << 17) | ((key[6] & 0x04) << 16) |
46  ((key[5] & 0x04) << 15) | ((key[4] & 0x04) << 14) |
47  ((key[3] & 0x04) << 13) | ((key[2] & 0x04) << 12) |
48  ((key[1] & 0x04) << 11) | ((key[0] & 0x04) << 10) |
49  ((key[7] & 0x08) << 8) | ((key[6] & 0x08) << 7) |
50  ((key[5] & 0x08) << 6) | ((key[4] & 0x08) << 5) |
51  ((key[3] & 0x08) << 4) | ((key[2] & 0x08) << 3) |
52  ((key[1] & 0x08) << 2) | ((key[0] & 0x08) << 1) |
53  ((key[3] & 0x10) >> 1) | ((key[2] & 0x10) >> 2) |
54  ((key[1] & 0x10) >> 3) | ((key[0] & 0x10) >> 4);
55 
56  for(size_t i = 0; i != 16; ++i)
57  {
58  C = ((C << ROT[i]) | (C >> (28-ROT[i]))) & 0x0FFFFFFF;
59  D = ((D << ROT[i]) | (D >> (28-ROT[i]))) & 0x0FFFFFFF;
60  round_key[2*i ] = ((C & 0x00000010) << 22) | ((C & 0x00000800) << 17) |
61  ((C & 0x00000020) << 16) | ((C & 0x00004004) << 15) |
62  ((C & 0x00000200) << 11) | ((C & 0x00020000) << 10) |
63  ((C & 0x01000000) >> 6) | ((C & 0x00100000) >> 4) |
64  ((C & 0x00010000) << 3) | ((C & 0x08000000) >> 2) |
65  ((C & 0x00800000) << 1) | ((D & 0x00000010) << 8) |
66  ((D & 0x00000002) << 7) | ((D & 0x00000001) << 2) |
67  ((D & 0x00000200) ) | ((D & 0x00008000) >> 2) |
68  ((D & 0x00000088) >> 3) | ((D & 0x00001000) >> 7) |
69  ((D & 0x00080000) >> 9) | ((D & 0x02020000) >> 14) |
70  ((D & 0x00400000) >> 21);
71  round_key[2*i+1] = ((C & 0x00000001) << 28) | ((C & 0x00000082) << 18) |
72  ((C & 0x00002000) << 14) | ((C & 0x00000100) << 10) |
73  ((C & 0x00001000) << 9) | ((C & 0x00040000) << 6) |
74  ((C & 0x02400000) << 4) | ((C & 0x00008000) << 2) |
75  ((C & 0x00200000) >> 1) | ((C & 0x04000000) >> 10) |
76  ((D & 0x00000020) << 6) | ((D & 0x00000100) ) |
77  ((D & 0x00000800) >> 1) | ((D & 0x00000040) >> 3) |
78  ((D & 0x00010000) >> 4) | ((D & 0x00000400) >> 5) |
79  ((D & 0x00004000) >> 10) | ((D & 0x04000000) >> 13) |
80  ((D & 0x00800000) >> 14) | ((D & 0x00100000) >> 18) |
81  ((D & 0x01000000) >> 24) | ((D & 0x08000000) >> 26);
82  }
83  }
84 
85 inline uint32_t spbox(uint32_t T0, uint32_t T1)
86  {
87  return DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^
88  DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^
89  DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^
90  DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)];
91  }
92 
93 /*
94 * DES Encryption
95 */
96 inline void des_encrypt(uint32_t& Lr, uint32_t& Rr,
97  const uint32_t round_key[32])
98  {
99  uint32_t L = Lr;
100  uint32_t R = Rr;
101  for(size_t i = 0; i != 16; i += 2)
102  {
103  L ^= spbox(rotr<4>(R) ^ round_key[2*i ], R ^ round_key[2*i+1]);
104  R ^= spbox(rotr<4>(L) ^ round_key[2*i+2], L ^ round_key[2*i+3]);
105  }
106 
107  Lr = L;
108  Rr = R;
109  }
110 
111 inline void des_encrypt_x2(uint32_t& L0r, uint32_t& R0r,
112  uint32_t& L1r, uint32_t& R1r,
113  const uint32_t round_key[32])
114  {
115  uint32_t L0 = L0r;
116  uint32_t R0 = R0r;
117  uint32_t L1 = L1r;
118  uint32_t R1 = R1r;
119 
120  for(size_t i = 0; i != 16; i += 2)
121  {
122  L0 ^= spbox(rotr<4>(R0) ^ round_key[2*i ], R0 ^ round_key[2*i+1]);
123  L1 ^= spbox(rotr<4>(R1) ^ round_key[2*i ], R1 ^ round_key[2*i+1]);
124 
125  R0 ^= spbox(rotr<4>(L0) ^ round_key[2*i+2], L0 ^ round_key[2*i+3]);
126  R1 ^= spbox(rotr<4>(L1) ^ round_key[2*i+2], L1 ^ round_key[2*i+3]);
127  }
128 
129  L0r = L0;
130  R0r = R0;
131  L1r = L1;
132  R1r = R1;
133  }
134 
135 /*
136 * DES Decryption
137 */
138 inline void des_decrypt(uint32_t& Lr, uint32_t& Rr,
139  const uint32_t round_key[32])
140  {
141  uint32_t L = Lr;
142  uint32_t R = Rr;
143  for(size_t i = 16; i != 0; i -= 2)
144  {
145  L ^= spbox(rotr<4>(R) ^ round_key[2*i - 2], R ^ round_key[2*i - 1]);
146  R ^= spbox(rotr<4>(L) ^ round_key[2*i - 4], L ^ round_key[2*i - 3]);
147  }
148  Lr = L;
149  Rr = R;
150  }
151 
152 inline void des_decrypt_x2(uint32_t& L0r, uint32_t& R0r,
153  uint32_t& L1r, uint32_t& R1r,
154  const uint32_t round_key[32])
155  {
156  uint32_t L0 = L0r;
157  uint32_t R0 = R0r;
158  uint32_t L1 = L1r;
159  uint32_t R1 = R1r;
160 
161  for(size_t i = 16; i != 0; i -= 2)
162  {
163  L0 ^= spbox(rotr<4>(R0) ^ round_key[2*i - 2], R0 ^ round_key[2*i - 1]);
164  L1 ^= spbox(rotr<4>(R1) ^ round_key[2*i - 2], R1 ^ round_key[2*i - 1]);
165 
166  R0 ^= spbox(rotr<4>(L0) ^ round_key[2*i - 4], L0 ^ round_key[2*i - 3]);
167  R1 ^= spbox(rotr<4>(L1) ^ round_key[2*i - 4], L1 ^ round_key[2*i - 3]);
168  }
169 
170  L0r = L0;
171  R0r = R0;
172  L1r = L1;
173  R1r = R1;
174  }
175 
176 inline void des_IP(uint32_t& L, uint32_t& R, const uint8_t block[])
177  {
178  // IP sequence by Wei Dai, taken from public domain Crypto++
179  L = load_be<uint32_t>(block, 0);
180  R = load_be<uint32_t>(block, 1);
181 
182  uint32_t T;
183  R = rotl<4>(R);
184  T = (L ^ R) & 0xF0F0F0F0;
185  L ^= T;
186  R = rotr<20>(R ^ T);
187  T = (L ^ R) & 0xFFFF0000;
188  L ^= T;
189  R = rotr<18>(R ^ T);
190  T = (L ^ R) & 0x33333333;
191  L ^= T;
192  R = rotr<6>(R ^ T);
193  T = (L ^ R) & 0x00FF00FF;
194  L ^= T;
195  R = rotl<9>(R ^ T);
196  T = (L ^ R) & 0xAAAAAAAA;
197  L = rotl<1>(L ^ T);
198  R ^= T;
199  }
200 
201 inline void des_FP(uint32_t L, uint32_t R, uint8_t out[])
202  {
203  // FP sequence by Wei Dai, taken from public domain Crypto++
204  uint32_t T;
205 
206  R = rotr<1>(R);
207  T = (L ^ R) & 0xAAAAAAAA;
208  R ^= T;
209  L = rotr<9>(L ^ T);
210  T = (L ^ R) & 0x00FF00FF;
211  R ^= T;
212  L = rotl<6>(L ^ T);
213  T = (L ^ R) & 0x33333333;
214  R ^= T;
215  L = rotl<18>(L ^ T);
216  T = (L ^ R) & 0xFFFF0000;
217  R ^= T;
218  L = rotl<20>(L ^ T);
219  T = (L ^ R) & 0xF0F0F0F0;
220  R ^= T;
221  L = rotr<4>(L ^ T);
222 
223  store_be(out, R, L);
224  }
225 
226 }
227 
228 /*
229 * DES Encryption
230 */
231 void DES::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
232  {
233  verify_key_set(m_round_key.empty() == false);
234 
235  while(blocks >= 2)
236  {
237  uint32_t L0, R0;
238  uint32_t L1, R1;
239 
240  des_IP(L0, R0, in);
241  des_IP(L1, R1, in + BLOCK_SIZE);
242 
243  des_encrypt_x2(L0, R0, L1, R1, m_round_key.data());
244 
245  des_FP(L0, R0, out);
246  des_FP(L1, R1, out + BLOCK_SIZE);
247 
248  in += 2*BLOCK_SIZE;
249  out += 2*BLOCK_SIZE;
250  blocks -= 2;
251  }
252 
253  for(size_t i = 0; i < blocks; ++i)
254  {
255  uint32_t L, R;
256  des_IP(L, R, in + BLOCK_SIZE*i);
257  des_encrypt(L, R, m_round_key.data());
258  des_FP(L, R, out + BLOCK_SIZE*i);
259  }
260  }
261 
262 /*
263 * DES Decryption
264 */
265 void DES::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
266  {
267  verify_key_set(m_round_key.empty() == false);
268 
269  while(blocks >= 2)
270  {
271  uint32_t L0, R0;
272  uint32_t L1, R1;
273 
274  des_IP(L0, R0, in);
275  des_IP(L1, R1, in + BLOCK_SIZE);
276 
277  des_decrypt_x2(L0, R0, L1, R1, m_round_key.data());
278 
279  des_FP(L0, R0, out);
280  des_FP(L1, R1, out + BLOCK_SIZE);
281 
282  in += 2*BLOCK_SIZE;
283  out += 2*BLOCK_SIZE;
284  blocks -= 2;
285  }
286 
287  for(size_t i = 0; i < blocks; ++i)
288  {
289  uint32_t L, R;
290  des_IP(L, R, in + BLOCK_SIZE*i);
291  des_decrypt(L, R, m_round_key.data());
292  des_FP(L, R, out + BLOCK_SIZE*i);
293  }
294  }
295 
296 /*
297 * DES Key Schedule
298 */
299 void DES::key_schedule(const uint8_t key[], size_t)
300  {
301  m_round_key.resize(32);
302  des_key_schedule(m_round_key.data(), key);
303  }
304 
306  {
307  zap(m_round_key);
308  }
309 
310 /*
311 * TripleDES Encryption
312 */
313 void TripleDES::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
314  {
315  verify_key_set(m_round_key.empty() == false);
316 
317  while(blocks >= 2)
318  {
319  uint32_t L0, R0;
320  uint32_t L1, R1;
321 
322  des_IP(L0, R0, in);
323  des_IP(L1, R1, in + BLOCK_SIZE);
324 
325  des_encrypt_x2(L0, R0, L1, R1, &m_round_key[0]);
326  des_decrypt_x2(R0, L0, R1, L1, &m_round_key[32]);
327  des_encrypt_x2(L0, R0, L1, R1, &m_round_key[64]);
328 
329  des_FP(L0, R0, out);
330  des_FP(L1, R1, out + BLOCK_SIZE);
331 
332  in += 2*BLOCK_SIZE;
333  out += 2*BLOCK_SIZE;
334  blocks -= 2;
335  }
336 
337  for(size_t i = 0; i != blocks; ++i)
338  {
339  uint32_t L, R;
340  des_IP(L, R, in + BLOCK_SIZE*i);
341 
342  des_encrypt(L, R, &m_round_key[0]);
343  des_decrypt(R, L, &m_round_key[32]);
344  des_encrypt(L, R, &m_round_key[64]);
345 
346  des_FP(L, R, out + BLOCK_SIZE*i);
347  }
348  }
349 
350 /*
351 * TripleDES Decryption
352 */
353 void TripleDES::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
354  {
355  verify_key_set(m_round_key.empty() == false);
356 
357  while(blocks >= 2)
358  {
359  uint32_t L0, R0;
360  uint32_t L1, R1;
361 
362  des_IP(L0, R0, in);
363  des_IP(L1, R1, in + BLOCK_SIZE);
364 
365  des_decrypt_x2(L0, R0, L1, R1, &m_round_key[64]);
366  des_encrypt_x2(R0, L0, R1, L1, &m_round_key[32]);
367  des_decrypt_x2(L0, R0, L1, R1, &m_round_key[0]);
368 
369  des_FP(L0, R0, out);
370  des_FP(L1, R1, out + BLOCK_SIZE);
371 
372  in += 2*BLOCK_SIZE;
373  out += 2*BLOCK_SIZE;
374  blocks -= 2;
375  }
376 
377  for(size_t i = 0; i != blocks; ++i)
378  {
379  uint32_t L, R;
380  des_IP(L, R, in + BLOCK_SIZE*i);
381 
382  des_decrypt(L, R, &m_round_key[64]);
383  des_encrypt(R, L, &m_round_key[32]);
384  des_decrypt(L, R, &m_round_key[0]);
385 
386  des_FP(L, R, out + BLOCK_SIZE*i);
387  }
388  }
389 
390 /*
391 * TripleDES Key Schedule
392 */
393 void TripleDES::key_schedule(const uint8_t key[], size_t length)
394  {
395  m_round_key.resize(3*32);
396  des_key_schedule(&m_round_key[0], key);
397  des_key_schedule(&m_round_key[32], key + 8);
398 
399  if(length == 24)
400  des_key_schedule(&m_round_key[64], key + 16);
401  else
402  copy_mem(&m_round_key[64], &m_round_key[0], 32);
403  }
404 
406  {
407  zap(m_round_key);
408  }
409 
410 }
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition: des.cpp:265
const uint32_t DES_SPBOX6[256]
Definition: des_tab.cpp:237
const uint32_t DES_SPBOX7[256]
Definition: des_tab.cpp:282
void verify_key_set(bool cond) const
Definition: sym_algo.h:89
void zap(std::vector< T, Alloc > &vec)
Definition: secmem.h:170
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition: des.cpp:353
void store_be(uint16_t in, uint8_t out[2])
Definition: loadstor.h:438
uint32_t load_be< uint32_t >(const uint8_t in[], size_t off)
Definition: loadstor.h:179
constexpr uint8_t get_byte(size_t byte_num, T input)
Definition: loadstor.h:41
const uint32_t DES_SPBOX4[256]
Definition: des_tab.cpp:147
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition: des.cpp:313
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition: des.cpp:231
const uint32_t DES_SPBOX3[256]
Definition: des_tab.cpp:102
const uint32_t DES_SPBOX8[256]
Definition: des_tab.cpp:327
const uint32_t DES_SPBOX1[256]
Definition: des_tab.cpp:12
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:122
Definition: alg_id.cpp:13
const uint32_t DES_SPBOX5[256]
Definition: des_tab.cpp:192
const uint32_t DES_SPBOX2[256]
Definition: des_tab.cpp:57
fe T
Definition: ge.cpp:37
void clear() override
Definition: des.cpp:305
void clear() override
Definition: des.cpp:405