Botan  2.7.0
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 
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 inline uint32_t spbox(uint32_t T0, uint32_t T1)
85  {
86  return DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^
87  DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^
88  DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^
89  DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)];
90  }
91 
92 /*
93 * DES Encryption
94 */
95 inline void des_encrypt(uint32_t& Lr, uint32_t& Rr,
96  const uint32_t round_key[32])
97  {
98  uint32_t L = Lr;
99  uint32_t R = Rr;
100  for(size_t i = 0; i != 16; i += 2)
101  {
102  L ^= spbox(rotr<4>(R) ^ round_key[2*i ], R ^ round_key[2*i+1]);
103  R ^= spbox(rotr<4>(L) ^ round_key[2*i+2], L ^ round_key[2*i+3]);
104  }
105 
106  Lr = L;
107  Rr = R;
108  }
109 
110 inline void des_encrypt_x2(uint32_t& L0r, uint32_t& R0r,
111  uint32_t& L1r, uint32_t& R1r,
112  const uint32_t round_key[32])
113  {
114  uint32_t L0 = L0r;
115  uint32_t R0 = R0r;
116  uint32_t L1 = L1r;
117  uint32_t R1 = R1r;
118 
119  for(size_t i = 0; i != 16; i += 2)
120  {
121  L0 ^= spbox(rotr<4>(R0) ^ round_key[2*i ], R0 ^ round_key[2*i+1]);
122  L1 ^= spbox(rotr<4>(R1) ^ round_key[2*i ], R1 ^ round_key[2*i+1]);
123 
124  R0 ^= spbox(rotr<4>(L0) ^ round_key[2*i+2], L0 ^ round_key[2*i+3]);
125  R1 ^= spbox(rotr<4>(L1) ^ round_key[2*i+2], L1 ^ round_key[2*i+3]);
126  }
127 
128  L0r = L0;
129  R0r = R0;
130  L1r = L1;
131  R1r = R1;
132  }
133 
134 /*
135 * DES Decryption
136 */
137 inline void des_decrypt(uint32_t& Lr, uint32_t& Rr,
138  const uint32_t round_key[32])
139  {
140  uint32_t L = Lr;
141  uint32_t R = Rr;
142  for(size_t i = 16; i != 0; i -= 2)
143  {
144  L ^= spbox(rotr<4>(R) ^ round_key[2*i - 2], R ^ round_key[2*i - 1]);
145  R ^= spbox(rotr<4>(L) ^ round_key[2*i - 4], L ^ round_key[2*i - 3]);
146  }
147  Lr = L;
148  Rr = R;
149  }
150 
151 inline void des_decrypt_x2(uint32_t& L0r, uint32_t& R0r,
152  uint32_t& L1r, uint32_t& R1r,
153  const uint32_t round_key[32])
154  {
155  uint32_t L0 = L0r;
156  uint32_t R0 = R0r;
157  uint32_t L1 = L1r;
158  uint32_t R1 = R1r;
159 
160  for(size_t i = 16; i != 0; i -= 2)
161  {
162  L0 ^= spbox(rotr<4>(R0) ^ round_key[2*i - 2], R0 ^ round_key[2*i - 1]);
163  L1 ^= spbox(rotr<4>(R1) ^ round_key[2*i - 2], R1 ^ round_key[2*i - 1]);
164 
165  R0 ^= spbox(rotr<4>(L0) ^ round_key[2*i - 4], L0 ^ round_key[2*i - 3]);
166  R1 ^= spbox(rotr<4>(L1) ^ round_key[2*i - 4], L1 ^ round_key[2*i - 3]);
167  }
168 
169  L0r = L0;
170  R0r = R0;
171  L1r = L1;
172  R1r = R1;
173  }
174 
175 inline void des_IP(uint32_t& L, uint32_t& R, const uint8_t block[])
176  {
177  uint64_t T = (DES_IPTAB1[block[0]] ) | (DES_IPTAB1[block[1]] << 1) |
178  (DES_IPTAB1[block[2]] << 2) | (DES_IPTAB1[block[3]] << 3) |
179  (DES_IPTAB1[block[4]] << 4) | (DES_IPTAB1[block[5]] << 5) |
180  (DES_IPTAB1[block[6]] << 6) | (DES_IPTAB2[block[7]] );
181 
182  L = static_cast<uint32_t>(T >> 32);
183  R = static_cast<uint32_t>(T);
184  }
185 
186 inline void des_FP(uint32_t L, uint32_t R, uint8_t out[])
187  {
188  uint64_t T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
189  (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
190  (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
191  (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
192  T = rotl<32>(T);
193 
194  store_be(T, out);
195  }
196 
197 }
198 
199 /*
200 * DES Encryption
201 */
202 void DES::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
203  {
204  verify_key_set(m_round_key.empty() == false);
205 
206  while(blocks >= 2)
207  {
208  uint32_t L0, R0;
209  uint32_t L1, R1;
210 
211  des_IP(L0, R0, in);
212  des_IP(L1, R1, in + BLOCK_SIZE);
213 
214  des_encrypt_x2(L0, R0, L1, R1, m_round_key.data());
215 
216  des_FP(L0, R0, out);
217  des_FP(L1, R1, out + BLOCK_SIZE);
218 
219  in += 2*BLOCK_SIZE;
220  out += 2*BLOCK_SIZE;
221  blocks -= 2;
222  }
223 
224  for(size_t i = 0; i < blocks; ++i)
225  {
226  uint32_t L, R;
227  des_IP(L, R, in + BLOCK_SIZE*i);
228  des_encrypt(L, R, m_round_key.data());
229  des_FP(L, R, out + BLOCK_SIZE*i);
230  }
231  }
232 
233 /*
234 * DES Decryption
235 */
236 void DES::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
237  {
238  verify_key_set(m_round_key.empty() == false);
239 
240  while(blocks >= 2)
241  {
242  uint32_t L0, R0;
243  uint32_t L1, R1;
244 
245  des_IP(L0, R0, in);
246  des_IP(L1, R1, in + BLOCK_SIZE);
247 
248  des_decrypt_x2(L0, R0, L1, R1, m_round_key.data());
249 
250  des_FP(L0, R0, out);
251  des_FP(L1, R1, out + BLOCK_SIZE);
252 
253  in += 2*BLOCK_SIZE;
254  out += 2*BLOCK_SIZE;
255  blocks -= 2;
256  }
257 
258  for(size_t i = 0; i < blocks; ++i)
259  {
260  uint32_t L, R;
261  des_IP(L, R, in + BLOCK_SIZE*i);
262  des_decrypt(L, R, m_round_key.data());
263  des_FP(L, R, out + BLOCK_SIZE*i);
264  }
265  }
266 
267 /*
268 * DES Key Schedule
269 */
270 void DES::key_schedule(const uint8_t key[], size_t)
271  {
272  m_round_key.resize(32);
273  des_key_schedule(m_round_key.data(), key);
274  }
275 
277  {
278  zap(m_round_key);
279  }
280 
281 /*
282 * TripleDES Encryption
283 */
284 void TripleDES::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
285  {
286  verify_key_set(m_round_key.empty() == false);
287 
288  while(blocks >= 2)
289  {
290  uint32_t L0, R0;
291  uint32_t L1, R1;
292 
293  des_IP(L0, R0, in);
294  des_IP(L1, R1, in + BLOCK_SIZE);
295 
296  des_encrypt_x2(L0, R0, L1, R1, &m_round_key[0]);
297  des_decrypt_x2(R0, L0, R1, L1, &m_round_key[32]);
298  des_encrypt_x2(L0, R0, L1, R1, &m_round_key[64]);
299 
300  des_FP(L0, R0, out);
301  des_FP(L1, R1, out + BLOCK_SIZE);
302 
303  in += 2*BLOCK_SIZE;
304  out += 2*BLOCK_SIZE;
305  blocks -= 2;
306  }
307 
308  for(size_t i = 0; i != blocks; ++i)
309  {
310  uint32_t L, R;
311  des_IP(L, R, in + BLOCK_SIZE*i);
312 
313  des_encrypt(L, R, &m_round_key[0]);
314  des_decrypt(R, L, &m_round_key[32]);
315  des_encrypt(L, R, &m_round_key[64]);
316 
317  des_FP(L, R, out + BLOCK_SIZE*i);
318  }
319  }
320 
321 /*
322 * TripleDES Decryption
323 */
324 void TripleDES::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
325  {
326  verify_key_set(m_round_key.empty() == false);
327 
328  while(blocks >= 2)
329  {
330  uint32_t L0, R0;
331  uint32_t L1, R1;
332 
333  des_IP(L0, R0, in);
334  des_IP(L1, R1, in + BLOCK_SIZE);
335 
336  des_decrypt_x2(L0, R0, L1, R1, &m_round_key[64]);
337  des_encrypt_x2(R0, L0, R1, L1, &m_round_key[32]);
338  des_decrypt_x2(L0, R0, L1, R1, &m_round_key[0]);
339 
340  des_FP(L0, R0, out);
341  des_FP(L1, R1, out + BLOCK_SIZE);
342 
343  in += 2*BLOCK_SIZE;
344  out += 2*BLOCK_SIZE;
345  blocks -= 2;
346  }
347 
348  for(size_t i = 0; i != blocks; ++i)
349  {
350  uint32_t L, R;
351  des_IP(L, R, in + BLOCK_SIZE*i);
352 
353  des_decrypt(L, R, &m_round_key[64]);
354  des_encrypt(R, L, &m_round_key[32]);
355  des_decrypt(L, R, &m_round_key[0]);
356 
357  des_FP(L, R, out + BLOCK_SIZE*i);
358  }
359  }
360 
361 /*
362 * TripleDES Key Schedule
363 */
364 void TripleDES::key_schedule(const uint8_t key[], size_t length)
365  {
366  m_round_key.resize(3*32);
367  des_key_schedule(&m_round_key[0], key);
368  des_key_schedule(&m_round_key[32], key + 8);
369 
370  if(length == 24)
371  des_key_schedule(&m_round_key[64], key + 16);
372  else
373  copy_mem(&m_round_key[64], &m_round_key[0], 32);
374  }
375 
377  {
378  zap(m_round_key);
379  }
380 
381 }
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition: des.cpp:236
const uint64_t DES_IPTAB2[256]
Definition: des_tab.cpp:438
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:193
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition: des.cpp:324
void store_be(uint16_t in, uint8_t out[2])
Definition: loadstor.h:434
const uint64_t DES_IPTAB1[256]
Definition: des_tab.cpp:372
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:284
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition: des.cpp:202
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:108
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
uint8_t get_byte(size_t byte_num, T input)
Definition: loadstor.h:39
const uint64_t DES_FPTAB1[256]
Definition: des_tab.cpp:504
void clear() override
Definition: des.cpp:276
void clear() override
Definition: des.cpp:376
const uint64_t DES_FPTAB2[256]
Definition: des_tab.cpp:570